C++ 调用函数并并行循环

C++ 调用函数并并行循环,c++,openmp,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 l

我没有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
for(int i=1;i
  • 一般来说,最好的方法是平均分配工作,以保持效率(无内核等待)例如,在您的情况下,静态调度可能不是一个好主意,因为40不能平均地除以150,在最后一次迭代中,您将失去25%的计算能力。因此,结果可能是,最好将
    parallel
    子句放在第二个循环之前。这一切取决于您选择的模式,以及实际工作的分布方式在循环内。例如,如果
    myfunction
    完成了99%的工作,那么这是个坏主意,如果99%的工作在两个内部循环内,那么这可能是个好主意

  • 不完全是。有3种调度模式。但它们都不能阻止其他线程。有一个任务池(迭代)这是分布在线程之间的。调度模式描述了将任务分配给线程的策略。当一个线程完成时,它只会得到下一个任务,不需要等待。这里更详细地描述了这些策略:(我不确定从wiki复制粘贴balant是否是一个好主意,因此我将留下一个链接。这是一个很好的材料。)

  • 可能这里没有写的是,模式开销是按照它们引入的开销的数量来表示的。
    静态的
    是最快的,然后是
    动态的
    ,然后是
    引导的
    。我的建议是,什么时候使用哪一种模式,这并不是最好的,但在我看来是很好的经验法则:

  • static
    如果您知道,将在线程之间平均分配,并花费相同的时间

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

  • guided
    用于相当长的任务,您几乎什么都说不出来


  • 如果您的任务很小,您甚至可以看到静态调度的开销(例如),但我认为在您的情况下,
    dynamic
    应该是最好的选择。

    您的代码片段不符合标准,因为您有两个嵌套的工作共享区域:您好,所以您的意思是,如果大部分工作都在函数调用中,那么将pragma omp留给我拥有的循环。但是如果大部分工作都在最后一个循环中,那么将pragma放入在第二个循环之前使用omp,对吗?而且也只因为我没有均匀分布的数据而使用dynamic?嗯,是的。一般来说,总是尝试找到一个将工作负载均匀分布的计划,按照这个顺序
    静态
    ->
    动态
    ->
    引导
    。在一般情况下,我没有什么可以说的了。我会测试一些方法我不知道你的程序,但我敢打赌,当前代码+动态调度将是最好的选择。这实际上取决于一个案例。另外,在我的最后一个循环(l循环)中如果我有sum+=..,我必须把pragma-omp屏障的sum放在上面吗?我认为这是多余的。你如何在这个级别上分割工作?如果你想要2级并行化,你可以为外部循环做10个线程,然后为内部循环做4个线程。但是我认为对于简单的求和来说,它不会很好地工作。
    #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++) {