只需编写一个小的omp测试,它就不能在任何时候正常工作:
#include <omp.h>
int main() {
int i,j=0;
#pragma omp parallel
for(i=0;i<1000;i++)
{
#pragma omp barrier
j+= j^i;
}
return j;
}在本例中,使用j从所有线程写入是不正确的,但是
用gcc-4.3.1 -fopenmp a.c -o gcc -static编译
在4核x86_Core2 Linux服务器上运行:$ ./gcc并冻结(有时,4-5快速运行时冻结1)。
斯特拉斯:
[pid 13118] futex(0x80d3014, FUTEX_WAKE, 1) = 1
[pid 13119] <... futex resumed> ) = 0
[pid 13118] futex(0x80d3020, FUTEX_WAIT, 251, NULL <unfinished ...>
[pid 13119] futex(0x80d3014, FUTEX_WAKE, 1) = 0
[pid 13119] futex(0x80d3020, FUTEX_WAIT, 251, NULL
<freeze>为什么我有一个冻结(死锁)?
发布于 2010-12-22 18:50:43
试着让我私有,这样每个循环都有自己的副本。
现在我有更多的时间,我将努力解释。默认情况下,OpenMP中的变量是共享的。有几种情况下,默认情况下变量是私有的。并行区域不是其中之一(因此高性能Mark的响应是错误的)。在最初的程序中,您有两个争用条件--一个在i上,一个在j上。问题是在I上。每个线程将执行循环几次,但是由于每个线程都更改了我,所以任何线程执行循环的次数都是不确定的。由于所有线程都必须执行barrier才能满足屏障的要求,所以需要在屏障上挂起一个永远不会结束的挂起,因为并不是所有线程都会执行相同的次数。
由于OpenMP规范明确规定(OMPspecV3.0,第2.8.3节屏障构造)“所遇到的工作共享区域和屏障区域的顺序必须对团队中的每个线程相同”,所以您的程序是不兼容的,因此可能有不确定的行为。
发布于 2010-12-20 23:18:28
您正在尝试从多个线程添加到同一个位置。你不能同时做你想做的事。如果你想并行地做一个和,你需要把它分成更小的部分,然后收集它们。
由a5b更新:正确的想法,但错误的部分代码被发现。i变量由两个线程更改。
发布于 2011-01-19 15:54:57
@ejd,如果我将我标记为私有,我的程序会遵守吗?
抱歉-我刚看到这个问题。从技术上讲,如果您将变量"i“标记为私有变量,则您的程序将符合OpenMP。但是,在"j“上仍然存在一个争用条件,虽然您的程序是兼容的(因为有一些有效的情况需要具有竞争条件),但"j”的值没有指定(根据OpenMP规范)。
在你之前的一个回答中,你说你试图测量障碍实现的速度。您可能需要查看几个“基准”,它们已经发布了各种OpenMP结构的结果。其中一篇由马克·布尔(EPCC,爱丁堡大学)撰写,另一篇(狮身人面像)来自劳伦斯·利弗莫尔国家实验室(LLNL),第三篇(Parkbench)来自日本计算机合作公司。他们可能会给你一些指导。
https://stackoverflow.com/questions/4491063
复制相似问题