首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >块中的OpenMP动态循环分解

块中的OpenMP动态循环分解
EN

Stack Overflow用户
提问于 2011-04-09 22:29:37
回答 3查看 4.6K关注 0票数 3

我正在使用OpenMP并行执行一个大的循环。假设我正在处理的数组总共有N个条目。我希望一个线程做前N/2个条目,另一个线程做最后的N/2。

我必须避免线程在相邻的条目上工作。大小N总是比线程的数量大得多,所以如果我能让OpenMP按照我上面概述的方式分发工作,我就不需要担心锁。

如果在编译时大小N是已知的,我可以使用#pragma omp parallel for schedule(static,N/2)。不幸的是,它不是。那么,我如何动态定义块大小呢?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-04-10 01:35:53

如果您不想使用内置openmp调度选项,如@Jonathan Dursi's answer所示,那么您可以自己实现所需的选项:

代码语言:javascript
复制
#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;
}

输出

代码语言:javascript
复制
0 0
0 1
0 2
0 3
0 4
1 5
1 6
1 7
1 8
1 9
票数 3
EN

Stack Overflow用户

发布于 2011-04-10 01:27:34

只要N在运行时是已知的,就没有问题;我不确定为什么您认为它必须在编译时已知。如果必须在编译时知道所有的事情,那么OMP循环构造的用处将非常有限。

代码语言:javascript
复制
#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;
}

它的运行非常简单,如下所示:

代码语言:javascript
复制
$ 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
票数 4
EN

Stack Overflow用户

发布于 2011-04-09 22:44:04

我在dotNET上遇到了类似的问题,并最终编写了一个智能队列对象,一旦这些对象可用,它将一次返回十几个对象。一旦我手头有了一个包,我就会决定一个可以一次性处理所有这些包的线程。

在解决这个问题时,我牢记W-queues比M-queues更好。有多个工人的一条长线比每个工人有一条线要好。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5605620

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档