OpenMP for 循环忽略 num_threads 子句
我在 VS2008 中有以下代码:(
int i,j;
bool pr = false;
#pragma omp parallel for private(pr) num_threads(2)
for(i=0;i<PIC_X;i++)
{
int rank = omp_get_thread_num();
int count = omp_get_num_threads();
if ( !pr )
{
printf_s("Hello from thread %d of %d\n", rank, count);
pr = true;
}
for(j=0;j<PIC_Y;j++)
{
// do stuff
}
}
如果您想知道的话,不尝试创建嵌套的 OpenMP 循环)。问题是,num_threads 子句没有任何效果:我只在输出中得到“Hello from thread 0 of 1”。我也尝试使用 omp_set_num_threads(2)
,但没有成功。什么给?
I have the following code in VS2008:
int i,j;
bool pr = false;
#pragma omp parallel for private(pr) num_threads(2)
for(i=0;i<PIC_X;i++)
{
int rank = omp_get_thread_num();
int count = omp_get_num_threads();
if ( !pr )
{
printf_s("Hello from thread %d of %d\n", rank, count);
pr = true;
}
for(j=0;j<PIC_Y;j++)
{
// do stuff
}
}
(Not trying to make a nested OpenMP loop, in case you're wondering). The problem is, the num_threads clause has no effect whatsoever: I only ever get "Hello from thread 0 of 1" on the output. I tried using omp_set_num_threads(2)
as well, to no avail. What gives?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您已将 pr 设置在并行区域之外,然后通过将其放入私有子句中将其设为私有。这意味着每个线程都有一个 pr,但私有 pr 变量没有初始化。 pr使用firstprivate而不是private,这样私有变量就被初始化了。
但是,您关于循环计数器默认为私有的说法是错误的。工作共享(或规范)(即变量 i)的循环计数器是私有的(OMP V2.0 规范的构造第 2.4.1 节)。但“j”不是。请参阅 OpenMP V2.0 规范(Microsoft 在 VS2008 中支持的规范),第 2.7.2 节数据共享属性子句:
至于 omp_get_num_threads() 返回 1,我能想到的是您没有在启用 OpenMP 标志的情况下编译它。
You have set pr outside of the parallel region and then made pr private by putting it in a private clause. That means that each thread has a pr, but the private pr variables are not initialized. Use firstprivate rather than private for pr, so that the private variables are initialized.
However, you are incorrect about loop counters being private by default. The loop counter for the worksharing (or canonical) for (i.e., the variable i) is private (section 2.4.1 for Construct of the OMP V2.0 spec). But "j" is not. See the OpenMP V2.0 spec (which is what Microsoft supports in VS2008), section 2.7.2 Data-Sharing Attribute Clauses:
As for omp_get_num_threads() returning a 1, all I can think of is that you didn't compile this wih the OpenMP flag enabled.
如果 OpenMP 将外层循环一分为二(即一个进程获取 0..PIC_X/2),另一个进程获取后一半,则只有一个进程会看到 i==0。
如果你的图像像我见过的所有图像一样组织,则外循环应该是 Y,内循环应该是 X,内循环应该是 OpenMP,因为这就是图像在内存中通常的组织方式。
If OpenMP splits the outer loop in 2 (i.e. one process gets 0..PIC_X/2) and the other gets the last half, only one process will see i==0.
And if your image is organized like all images I have seen, the outer loop should be Y and the inner loop should be X, and the inner loop should be OpenMP'ed, because that's how images are generally organized in memory.