极度放缓,OpenMP可能会看到未来的竞争条件?

时间:2016-01-04 19:44:12

标签: multithreading pointers openmp race-condition

当我添加(* pRandomTrial)++时,我在OpenMP上的代码变得很慢;产生随机数后。 to g_iRandomTrials [32]我存储了每个线程的rand()调用次数。每个线程写入这个数组的不同索引,没有竞争条件,结果都没问题,但是这个非常简单的计数器使程序比没有计数器慢10倍。在这种情况下我可以使用一些关键字吗?我尝试使用firstprivate(g_iRandomTrials)进行一些设置,但我从未成功过。当我在Simulate()函数中创建int计数器并且在函数的开始和结束时仅使用指针两次时,代码将运行得更快,但这似乎有点难看的解决方案,因为它没有对问题做任何事情...

    int g_iRandomTrials[32];

    ...

    #pragma omp parallel
    {
        do
        {
            ...
            Simulate();
            ...
        }
    }

    void Simulate(void)
    {
        ...
        int id=omp_get_thread_num();
        int*pRandomTrial=g_iRandomTrials+id;
        ...
        while (used[index])
        {
            index=rand()%50;
            (*pRandomTrial)++;
        }
    }

1 个答案:

答案 0 :(得分:0)

减速的原因称为虚假共享。答案是填充。

  

在计算机科学中,虚假共享是一种性能下降的用法   在具有分布式,连贯的缓存的系统中可能出现的模式   由缓存管理的最小资源块的大小   机制。当系统参与者尝试定期访问时   数据永远不会被另一方更改,但数据共享   具有被更改的数据的高速缓存块,高速缓存协议可以   迫使第一个参与者重新加载整个单位,尽管缺乏   逻辑必然性。缓存系统不知道其中的活动   这个块并迫使第一个参与者承担缓存系统   真正共享资源访问所需的开销。

https://en.wikipedia.org/wiki/False_sharing

CPU将内存锁定在称为缓存行的内容中。这些往往是64字节长。当一个核心访问变量时, 锁定 整个缓存行并从内存中获取它。在释放锁之前,其他核心无法再访问它。

答案是填充并对齐randomTrials,使得任何值都不会超出另一个值的64字节。请记住,64字节值是最常见的,但有些架构不同。