C ++ OpenMP:安排大小不等的任务

时间:2015-10-10 20:37:27

标签: c++ multithreading performance sorting openmp

我必须使用C ++中的OpenMP对矢量集合进行排序。我真的认为这应该是一个普遍的问题;但是,我从未发现任何关于它的事情。

当然我可以使用

  #pragma omp parallel for schedule(dynamic,1)
    for(int i =0; i<narrays; ++i)
      sortSerial(array[i]);

并将调度留给运行时。

但是,一个阵列可能需要比其他阵列组合更长的时间。实际上,我可能只有一个阵列。 或者说,我可能会有二万个,每个元素有一百个元素,另外两个元素各有一百万元素。在这种情况下,如果我有8个内核,我想为前四个线程分配每个线程的五千个部分,然后为每个部分分配两个个线程四强。这样总的时间就不变了。

然后我可能会使用嵌套并行性。但如果我这样做

  #pragma omp parallel for schedule(dynamic,1)
    for(int i =0; i<narrays; ++i)
      sortParallel(array[i]);

其中sortParallel产生正确数量的线程以平衡工作负载,OMP仍将开始处理尽可能多的线程;然后嵌套的并行性很可能会超额认购。这看起来很糟糕,特别是因为sortParallel例程有很多障碍。

理想的解决方案是告诉每次迭代需要多少次,以便在超额预订时可以避免启动新任务,但这似乎不可能。

我可能必须注意它应该在VisualStudio 2013下编译,因此,它似乎是OpenMP 2.0 - 特别是没有任务。

我现在正在探索平行区域深嵌套的奇怪组合。但我真的不愿意这样做。我缺少一些明显的解决方案吗?

我的最后一个设计是从这样一个事实开始的,即如果线程分割正确完成,那么大部分永远不会比总数/线程更长(太多)。如果我们在剩余的线程中正确划分它们,那么小部分也是如此。所以我们真的不需要争抢重用我们用来对更大的向量进行排序的线程;因为他们无论如何都会在同一时间完成(唉,大致)。 因此,我可以在不同的向量中划分长间隔和小间隔,在线程[i]中设置尝试创建最佳平衡的线程数的分区,然后执行此操作

void sort(int i,int threads){
    if(i<nbigintervals) //sort one big interval
       sortParallel(bigInterval[i],threads);  //spawns threads threads
    else                //sort all the others
       #pragma omp parallel for schedule(dynamic,1) num_threads(threads)  //nested parallel section, assigning the remaining vectors in dynamic fashion.
           for(int j=0;j<nsmallintervals;++j)
              sortSerial(smallInterval[j]);
}

int main() {
//....
//assign vectors of intervals
//balance threads

omp_set_nested(true);
#pragma omp parallel for schedule(static,1) num_threads(nbigintervals +1)
   for(int i=0; i<=nbigintervals; ++i) //notice the less _or equal_, which adds one iteration (and makes their number match the number of threads requested)
      sort(i,threads[i]);
 //....
 }

这可以避免超额订阅,因为每次迭代产生的线程都是为可用总和而设计的。有更简单/更清洁/更快的解决方案吗?

0 个答案:

没有答案