调用函数并并行循环

时间:2014-05-06 09:18:29

标签: c++ openmp

我在openMP方面没有任何经验,所以我想知道如何做以下事情:

for (int i = 1; i <= NumImages; i++) {

//call a function
myfunction(...);

for (int k = 0 ; k < SumNumber k++) {

   for (int l = 0; l < ElNum ; l++) {

       //do 2 summing up calculations inside a while loop

  }//end k loop

}//end i loop

现在,我可以使用40个核心。

NumImages将从50到150,通常为150。

SumNumber将在200左右。

ElNum将在5000左右。

那么,最好的处理方法是将每个线程分配给一个函数调用,并且还并行执行l循环?

如果是,那就像是:

#pragma omp parallel for num_threads(40)

    for (int i = 1; i <= NumImages; i++) {

       myfunction(...);

        for (int k = 0 ; k < SumNumber k++) {

           #pragma omp for
           for (int l = 0; l < ElNum ; l++) {

上述方法(对于NumImages = 150)myfunction将并行执行40次并且l循环然后,当l loop和k循环结束时,接下来的40个线程将再次调用该函数,接下来的40个,所以3 * 40 = 120然后是下一个30?

1 个答案:

答案 0 :(得分:0)

  1. 通常,最好的方法是均匀分割工作,以保持效率(没有核心等待)。例如。在你的情况下,静态调度可能不是一个好主意,因为40不会均匀地划分150,对于最后一次迭代,你将失去25%的计算能力。所以可能会发现,在第二个循环之前放置parallel子句会更好。这一切都取决于您选择的模式,以及如何在循环中分配实际工作。例如,如果myfunction做了99%,那么这是一个坏主意,如果99%的工作在2个内循环内,那可能是好的。

  2. 不是真的。有3种调度模式。但是它们都没有以某种方式工作,它阻止了其他线程。在线程之间分配有一组任务(迭代)。调度模式描述了将任务分配给线程的策略。当一个线程完成时,它只是下一个任务,没有等待。这里的策略有更详细的描述:http://en.wikipedia.org/wiki/OpenMP#Scheduling_clauses(我不确定wiki的balant-copy粘贴是否是一个好主意,所以我会留下一个链接。它是一个很好的材料。)

  3. 可能没有写的是模式开销是按照它们引入的开销量的顺序呈现的。 static最快,然后是dynamic,然后是guided。我的建议何时使用,这不是最好的,但是好的经验法则IMO:

    1. static如果您知道将在线程中平均分配并花费相同的时间

    2. dynamic如果您知道任务不会均匀分配或执行时间不均匀

    3. guided执行相当长的任务,你几乎无法说出任何内容

    4. 如果你的任务相当小,你甚至可以看到静态调度的开销(例如why my OpenMP C++ code is slower than a serial code?),但我认为在你的情况下dynamic应该是好的,也是最好的选择。