2017-10-17 267 views
0

之间的行动所以,我大致有这样的代码:OpenMP;嵌套循环

for (int i = 0; i != 10000; ++i) { 
    doAction(i); 
    for (int j = 0; j != 10000; ++j) { 
     ... 
    } 
} 

而且我想使用OpenMP来parallellize它。据我所知,在这种情况下,一个简单的collapse不会做;我尝试使用单独的#pragma omp for也没有结果。有没有简单的方法来轻松地并行化,或者我不得不求助于doActioni*j次?

+1

如何更换!= by <? – tim18

+0

@ tim18那应该做什么?我一直认为它们在这方面是等同的。另外,我不明白这与问题 – Akiiino

+1

的嵌套循环部分相关** [A]:**您是否考虑调用一个'doAction(i);'函数来表示*(cit )“在**嵌套循环之间的动作**”*? ** [B]:**您是如何认识到'doAction(i)'代码被称为**'i * j' **倍的? ** [C]:**在'...'里面的实际处理是什么? MCVE代码应该代表一个可重复的例子。如何验证这样的代码,而没有机会确认/拒绝安排一个“只”的可能性 - **'[CONCURRENT]'**或者真正的** ** [PARALLEL] **代码执行,一块MCVE代码实际上是缺少的? – user3666197

回答

1

并行化的简单方法,只使用OpenMP作为外部循环。

将所有东西并行化并不是一件好事,因为线程同步&任务调度开销。当您将大型CPU绑定任务拆分为并行执行时,最理想的情况是在大部分时间使用所有可用的CPU内核时应该尽可能大。

P.S.如果您有OpenMP 4,对于内部循环,则可能需要#pragma omp simd而不是parallel。外循环应该仍然是parallel。通过这种方式,您将同时使用两种并行机制,外部循环跨核心并行化,内部循环跨SIMD通道并行化。从理论上讲,这通常是计算东西的最快方法。

+0

这是一个很好的答案。虽然没有详细说明 - 但建议是正确的。根据需要并行化为细粒(内环)(用于暴露足够的单独工作项和负载平衡),但尽可能平行化为粗粒(用于保持较小的开销)。它让我感到困惑,为什么这是被低估的。 – Zulan