我正在使用OpenMP并行执行一个大的循环。假设我正在处理的数组总共有N个条目。我希望一个线程做前N/2个条目,另一个线程做最后的N/2。
我必须避免线程在相邻的条目上工作。大小N总是比线程的数量大得多,所以如果我能让OpenMP按照我上面概述的方式分发工作,我就不需要担心锁。
如果在编译时大小N是已知的,我可以使用#pragma omp parallel for schedule(static,N/2)
。不幸的是,它不是。那么,我如何动态定义块大小呢?
发布于 2011-04-10 01:35:53
如果您不想使用内置openmp调度选项,如@Jonathan Dursi's answer所示,那么您可以自己实现所需的选项:
#include <stdio.h>
#include <omp.h>
/* $ gcc -O3 -fopenmp -Wall *.c && ./a.out */
static void doloop(int n) {
int thread_num, num_threads, start, end, i;
#pragma omp parallel private(i,thread_num,num_threads,start,end)
{
thread_num = omp_get_thread_num();
num_threads = omp_get_num_threads();
start = thread_num * n / num_threads;
end = (thread_num + 1) * n / num_threads;
for (i = start; i != end; ++i) {
printf("%d %d\n", thread_num, i);
}
}
}
int main() {
omp_set_num_threads(2);
doloop(10);
return 0;
}
输出
0 0
0 1
0 2
0 3
0 4
1 5
1 6
1 7
1 8
1 9
发布于 2011-04-10 01:27:34
只要N在运行时是已知的,就没有问题;我不确定为什么您认为它必须在编译时已知。如果必须在编译时知道所有的事情,那么OMP循环构造的用处将非常有限。
#include <stdio.h>
#include <stdlib.h>
#include <omp.h>
int main(int argc, char **argv) {
int n;
int chunksize;
if (argc != 2) {
fprintf(stderr,"Usage: %s n, where n = number of iterations.\n", argv[0]);
exit(-1);
}
n = atoi(argv[1]);
if (n<1 || n>200) n = 10;
chunksize = n/2;
#pragma omp parallel num_threads(2) default(none) shared(n,chunksize)
{
int nthread = omp_get_thread_num();
#pragma omp for schedule(static,chunksize)
for (int i=0; i<n; i++) {
printf("Iter %d being done by thread %d\n", i, nthread);
}
}
return 0;
}
它的运行非常简单,如下所示:
$ gcc -v
[...]
gcc version 4.4.0 (GCC)
$ gcc -o loop loop.c -fopenmp
$ ./loop 10
Iter 5 being done by thread 1
Iter 6 being done by thread 1
Iter 7 being done by thread 1
Iter 8 being done by thread 1
Iter 9 being done by thread 1
Iter 0 being done by thread 0
Iter 1 being done by thread 0
Iter 2 being done by thread 0
Iter 3 being done by thread 0
Iter 4 being done by thread 0
发布于 2011-04-09 22:44:04
我在dotNET上遇到了类似的问题,并最终编写了一个智能队列对象,一旦这些对象可用,它将一次返回十几个对象。一旦我手头有了一个包,我就会决定一个可以一次性处理所有这些包的线程。
在解决这个问题时,我牢记W-queues比M-queues更好。有多个工人的一条长线比每个工人有一条线要好。
https://stackoverflow.com/questions/5605620
复制相似问题