OpenMP for 循环忽略 num_threads 子句

发布于 2024-10-16 06:57:48 字数 554 浏览 4 评论 0原文

我在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

乞讨 2024-10-23 06:57:48

您已将 pr 设置在并行区域之外,然后通过将其放入私有子句中将其设为私有。这意味着每个线程都有一个 pr,但私有 pr 变量没有初始化。 pr使用firstprivate而不是private,这样私有变量就被初始化了。

但是,您关于循环计数器默认为私有的说法是错误的。工作共享(或规范)(即变量 i)的循环计数器是私有的(OMP V2.0 规范的构造第 2.4.1 节)。但“j”不是。请参阅 OpenMP V2.0 规范(Microsoft 在 VS2008 中支持的规范),第 2.7.2 节数据共享属性子句:

如果遇到并行或工作共享构造时变量可见,并且
该变量未在共享属性子句或 threadprivate 中指定
指令,然后该变量被共享。动态中声明的静态变量
并行区域的范围是共享的。堆分配的内存(例如,使用
C 或 C++ 中的 malloc() 或 C++ 中的 new 运算符)是共享的。 (指向这个的指针
但是,内存可以是私有的,也可以是共享的。)具有自动存储功能的变量
在并行区域的动态范围内声明的持续时间是私有的。

至于 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:

If a variable is visible when a parallel or work-sharing construct is encountered, and
the variable is not specified in a sharing attribute clause or threadprivate
directive, then the variable is shared. Static variables declared within the dynamic
extent of a parallel region are shared. Heap allocated memory (for example, using
malloc() in C or C++ or the new operator in C++) is shared. (The pointer to this
memory, however, can be either private or shared.) Variables with automatic storage
duration declared within the dynamic extent of a parallel region are private.

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.

愁杀 2024-10-23 06:57:48

如果 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文