我正在尝试使用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部分?
提前致谢
答案 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
进行同步。