我正在尝试创建一个程序来创建一个数组,并使用 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/