极度减速,OpenMP 可能看到不存在的竞争条件?
Extreme slowdown, OpenMP probably see unexisting race conditions?
当我添加 (*pRandomTrial)++ 时,我在 OpenMP 上的代码变得非常慢;生成随机数后。 g_iRandomTrials[32] 我存储了每个线程的 rand() 调用次数。每个线程写入这个数组的不同索引,没有竞争条件,结果还可以,但是这个非常简单的计数器使程序比没有计数器慢了将近 10 倍。在这种情况下我可以使用一些关键字吗?我用 firstprivate(g_iRandomTrials) 尝试了一些设置,但我从来没有成功过。当我在 Simulate() 函数中创建 int counter 并在函数开始和结束时仅两次使用指针时,代码 运行 可能会快得多,但这似乎有点丑陋的解决方案,因为它没有关于这个问题...
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)++;
}
}
速度变慢的原因称为虚假分享。答案是填充。
In computer science, false sharing is a performance-degrading usage
pattern that can arise in systems with distributed, coherent caches at
the size of the smallest resource block managed by the caching
mechanism. When a system participant attempts to periodically access
data that will never be altered by another party, but that data shares
a cache block with data that is altered, the caching protocol may
force the first participant to reload the whole unit despite a lack of
logical necessity. The caching system is unaware of activity within
this block and forces the first participant to bear the caching system
overhead required by true shared access of a resource.
https://en.wikipedia.org/wiki/False_sharing
CPU 将内存锁定在称为缓存行的东西中。这些往往是 64 字节的长度。当一个核心访问一个变量时,它 锁定 整个缓存行并从内存中获取它。在释放锁之前,其他内核无法再访问它。
答案是以这样一种方式填充和对齐您的 randomTrials
,即任何值都不会在另一个值的 64 字节范围内。请记住,64 字节值是最常见的,但也有不同的体系结构。
当我添加 (*pRandomTrial)++ 时,我在 OpenMP 上的代码变得非常慢;生成随机数后。 g_iRandomTrials[32] 我存储了每个线程的 rand() 调用次数。每个线程写入这个数组的不同索引,没有竞争条件,结果还可以,但是这个非常简单的计数器使程序比没有计数器慢了将近 10 倍。在这种情况下我可以使用一些关键字吗?我用 firstprivate(g_iRandomTrials) 尝试了一些设置,但我从来没有成功过。当我在 Simulate() 函数中创建 int counter 并在函数开始和结束时仅两次使用指针时,代码 运行 可能会快得多,但这似乎有点丑陋的解决方案,因为它没有关于这个问题...
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)++;
}
}
速度变慢的原因称为虚假分享。答案是填充。
In computer science, false sharing is a performance-degrading usage pattern that can arise in systems with distributed, coherent caches at the size of the smallest resource block managed by the caching mechanism. When a system participant attempts to periodically access data that will never be altered by another party, but that data shares a cache block with data that is altered, the caching protocol may force the first participant to reload the whole unit despite a lack of logical necessity. The caching system is unaware of activity within this block and forces the first participant to bear the caching system overhead required by true shared access of a resource.
https://en.wikipedia.org/wiki/False_sharing
CPU 将内存锁定在称为缓存行的东西中。这些往往是 64 字节的长度。当一个核心访问一个变量时,它 锁定 整个缓存行并从内存中获取它。在释放锁之前,其他内核无法再访问它。
答案是以这样一种方式填充和对齐您的 randomTrials
,即任何值都不会在另一个值的 64 字节范围内。请记住,64 字节值是最常见的,但也有不同的体系结构。