到目前为止,我一直在使用omp
仅用于大周期,因为它很容易编写,并且这些周期大部分时间都在消耗。但是,有时我需要做一些只能在一个线程中有效完成的I / O,但通常这个I / O独立于(下一个)循环。
我需要做这样的事情:
print_something(); // independet
print_something_else(); // independent
for(...){...}; // large cycle independent on previous printing
如何使用omp
在一个线程中执行print_something
,在第二个线程中使用print_something_else
并使用所有剩余线程来计算循环?并且因为循环很可能比执行打印函数花费更多时间,如何在完成后将执行I / O的两个线程添加到循环中?
这样的事情会起作用吗?
#pragma omp parallel
{
#pragma omp sections
{
#pragma omp section
{
print_something();
}
#pragma omp section
{
print_something_else();
}
}
#pragma omp for
for(...){...};
}
答案 0 :(得分:2)
#pragma omp section
有一个隐含的障碍,因此应用程序将在运行#pragma omp for
之前等待这些部分完成。另一种方法是在pragma omp部分添加nowait子句。所以这将是运行代码的替代方法:
#pragma omp parallel
{
#pragma omp sections nowait
{
#pragma omp section
{
print_something();
}
#pragma omp section
{
print_something_else();
}
}
#pragma omp for
for(...){...};
}
但这种方法存在问题。 #pragma omp for
可以使用静态调度,这意味着它将在线程组之间分配for循环的工作,包括运行这些部分的工作。在这种情况下,parallel for必须等待各部分完成。解决的一种方法是在for循环上使用不同的调度(例如动态或引导)。
如果您的编译器支持OpenMP任务构造,我相信任务可以让您更好地表达您正在寻找的这种不规则并行性。 SO中的其他question对部分和任务之间的差异有很好的答案。