我想在openMP中并行运行以下代码:
while (!stopcondition())
{
work_1();
work_2(); //work_2 has to be run after work_1
}
其中work()函数易于并行化:
work_i()
{
//...some linear stuff...//
#pragma omp parallel for schedule(static, 2) // make a piece of size 2 for each thread
for(int n=0; n<N; ++n)
printf(" %d", omp_get_thread_num() );
}
在while循环或work()函数中设置并行区域是不方便的,因为它会导致每次都分割线程,这会导致很大的开销。
当我尝试时:
#pragma omp parallel
{
#pragma omp single
{
while (!stopcondition())
{
work_1();
work_2();
}
}
}
然后work_1和work_2总是打印相同的id,因此它肯定由同一个线程执行。
1)我怎样才能克服它? 2)我应该从work()中提取//线性东西//并将其放在#pragma omp single中吗?
3)初始化并行区域的最佳位置在哪里?
----------------------编辑-----------------
似乎唯一的方法是从work()中删除这些东西并将其封装在一个公共的并行区域中:
while (!stopcondition())
{
#pragma omp parallel
{
#pragma omp parallel for schedule(static, 2) // make a piece of size 2 for each thread
for(int n=0; n<N; ++n)
printf("Piece of work_1 %d", omp_get_thread_num() );
#pragma omp parallel for schedule(static, 2) // make a piece of size 2 for each thread
for(int n=0; n<N; ++n)
printf("Piece of work_2 %d", omp_get_thread_num() );
}
//...rest of linear stuff...//
}
答案 0 :(得分:0)
您上次解决方案的问题:
while (!stopcondition())
{
#pragma omp parallel
{
#pragma omp parallel for schedule(static, 2) // make a piece of size 2 for each thread
for(int n=0; n<N; ++n)
printf("Piece of work_1 %d", omp_get_thread_num() );
#pragma omp parallel for schedule(static, 2) // make a piece of size 2 for each thread
for(int n=0; n<N; ++n)
printf("Piece of work_2 %d", omp_get_thread_num() );
}
//...rest of linear stuff...//
}
循环的每次迭代都会产生线程,这对性能不利。此外,您有嵌套的并行区域,这取决于您使用的OpenMP,可以创建线程的超额订阅:由第一个并行产生的每个线程将为每个内部并行区域生成一组新线程;这是正确的,但不是最佳的。
解决方案是:
#pragma omp parallel
{
while (!stopcondition())
{
work_1();
#pragma omp barrier /*So you make sure work_2 is executed after work_1*/
work_2(); //work_2 has to be run after work_1
}
}
现在,根据你的stopcondition()
函数的作用,你可能需要一些同步来确保没有竞争条件,并且所有线程都正确地退出循环。