OpenMP划分核心循环

时间:2011-11-29 14:37:51

标签: c++ openmp

我正在尝试使用sse指令和openmp在parrallel中执行一些应用程序。 关于openmp部分,我的代码如下:

for(r=0; r<end_condition; r++){
    .. several nested for loops inside ..
}

我想在多个内核上将此循环划分为r,例如,当使用两个内核时,一个内核应执行r = 0 .. r = end_condition / 2-1而另一个r = end_condition / 2 .. r = end_condition-1。循环的迭代之间没有通信,因此可以并行运行,在r循环结束时,结果应该同步。

如何使用openmp指令以这种方式在内核上划分?我是否必须在r上展开循环并使用openmp部分?

提前致谢

4 个答案:

答案 0 :(得分:1)

你可以通过添加:

来实现这一目标
#pragma omp parallel for
for(r=0; r<end_condition; r++){
    .. several nested for loops inside ..
}

但是,您需要确保循环中共享的内容和私有内容。虽然这并不能保证你按照你提到的那样划分r。如果您想以这种显式方式使用它,您可以使用任务。但手工完成并不是很方便,我不推荐它。

答案 1 :(得分:1)

使用以下代码,编译器会生成一个并行区域,该区域由N个线程执行。

omp_set_num_threads(N);

#pragma omp parallel for
for(int r = 0; r < end_condition; ++r)
{
    .. several nested for loops inside ..
}

每个线程都从end_condition执行一个子集。请注意,您的计数变量r现在在范围内的omp并行内声明。现在每个线程都有自己的计数变量。

使用并行编译指示可以实现相同的目标,而不是并行,例如:

omp_set_num_threads(N);
#pragma omp parallel private(r)
{
   int tid = omp_get_thread_num();
   for(r = (end_condition/N) * tid; r < (end_condition/N) * (tid+1) ; ++r)
   {
    .. several nested for loops inside ..
   }
}

当然只有当end_condition%N = 0但你才能得到这笔交易。这里变量r被明确标记为线程的私有,并且可以被声明为你想要的。编译器将为每个线程生成一个副本。

答案 2 :(得分:0)

您可以设置for循环应创建的线程数。对于每个线程,您可以指定块大小。

答案 3 :(得分:0)

我只能补充一点,如果不同的循环迭代需要不同的时间,你可能会遇到问题 - 在这种情况下你想要添加schedule (dynamic)

#pragma omp parallel for schedule (dynamic)
for(r=0; r<end_condition; r++){
    .. several nested for loops inside ..
}

另外,请注意,在循环结束时会自动添加barrier,因此您可以确保仅在所有迭代完成后继续执行。如果不需要(你还有一些与循环并行的工作) - 将nowait添加到for指令参数中。然后,您可以请求与#pragma omp barrier进行同步。