c - 指定线程访问数组中的哪些位置

标签 c openmp

我正在尝试创建一个程序来创建一个数组,并使用 OpenMP 为该数组中的每个位置分配值。这将是微不足道的,除了我想指定一个数组负责哪些位置。

例如,如果我有一个长度为 80 和 8 个线程的数组,我想确保线程 0 只写入位置 0-9,线程 1 写入位置 10-19 等等。

我是 OpenMP 的新手,所以我尝试了以下方法:

#include <omp.h>
#include <stdio.h>
#define N       80

int main (int argc, char *argv[]) 
{
    int nthreads = 8, tid, i, base, a[N];

    #pragma omp parallel
    {
        tid = omp_get_thread_num();
        base = ((float)tid/(float)nthreads) * N;
        for (i = 0; i < N/nthreads; i++) {
            a[base + i] = 0;
            printf("%d %d\n", tid, base+i);
        }
    }
    return 0;
}

然而,这个程序并没有像我预期的那样访问所有位置。每次运行输出都不一样,例如:

4 40
5 51
5 52
5 53
5 54
5 55
5 56
5 57
5 58
5 59
5 50
4 40
6 60
6 60
3 30
0 0
1 10

我想我缺少一个指令,但我不知道它是哪一个。

最佳答案

确保事情按您想要的方式工作的方法是将一个只有 8 次迭代的循环作为外部(并行)循环,并让每个线程执行一个仅访问正确元素的内部循环:

#pragma omp parallel for private(j)
   for(i = 0; i < 8; i++) {
     for(j = 0; j < 10; j++) {
       a[10*i+j] = 0;
       printf("thread %d updated element %d\n", omp_get_thread_num(), 8*i+j);
     }
   }

我现在无法对此进行测试,但我 90% 确定这完全符合您的要求(并且当您这样做时,您可以“完全控制”事情的运作方式)。然而,这可能不是最有效的做法。一方面 - 当您只想将一堆元素设置为零时,您想要使用像 memset 这样的内置函数,而不是循环...

关于c - 指定线程访问数组中的哪些位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19954229/

相关文章:

openmp - 如何获取程序整个执行过程中可能创建的最大 OpenMP 线程数?

c++ - openmp 程序卡在 block 的末尾

c++ - 使用重载运算符减少 OpenMP

c++ - OpenMP:通过线程 ID 访问共享变量时是否需要临界区

c - C 中的无符号 int 表现为负数

c++ - 在 Borland C++ 编译器 5.5 中询问文件 .obj 和 .tds

c++ - c++ 可执行文件中存储了多少源信息

C 打印 1-10,有问题

c - 使用 GNU/GCC 四精度库出错

linux - OpenMP: "implicit barrier"中有 20% 的时间?