当我添加(* 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)++;
}
}
答案 0 :(得分:0)
减速的原因称为虚假共享。答案是填充。
在计算机科学中,虚假共享是一种性能下降的用法 在具有分布式,连贯的缓存的系统中可能出现的模式 由缓存管理的最小资源块的大小 机制。当系统参与者尝试定期访问时 数据永远不会被另一方更改,但数据共享 具有被更改的数据的高速缓存块,高速缓存协议可以 迫使第一个参与者重新加载整个单位,尽管缺乏 逻辑必然性。缓存系统不知道其中的活动 这个块并迫使第一个参与者承担缓存系统 真正共享资源访问所需的开销。
https://en.wikipedia.org/wiki/False_sharing
CPU将内存锁定在称为缓存行的内容中。这些往往是64字节长。当一个核心访问变量时, 锁定 整个缓存行并从内存中获取它。在释放锁之前,其他核心无法再访问它。
答案是填充并对齐randomTrials
,使得任何值都不会超出另一个值的64字节。请记住,64字节值是最常见的,但有些架构不同。