openMP 条件杂注"如果否则"

openMP conditional pragma "if else"

本文关键字:如果 条件 openMP      更新时间:2023-10-16

我有一个for循环,可以根据条件使用schedule(static)schedule(dynamic, 10)执行。目前,我的代码不够DRY(不要重复自己),为了适应以前的功能,它有以下重复:

boolean isDynamic; //can be true or false
if(isDynamic){
    #pragma omp parallel for num_threads(thread_count) default(shared) private(...) schedule(dynamic, 10)
    for(...){
        //for code inside
    }
}else{
    #pragma omp parallel for num_threads(thread_count) default(shared) private(...) schedule(static)
    for(...){
        //SAME for code inside, in fact, this is the EXACT same for as before
    }
}

阅读这些线程后,我注意到openMP有一个#if(expression) pragma:

  • OpenMP:有条件使用#pragma
  • http://msdn.microsoft.com/en-us/library/5187hzke.aspx
  • 根据条件
  • 选择OpenMP编译
  • 条件"pragma comp& quot;
  • http://openmp.org/mp-documents/ntu-vanderpas.pdf

但是,尽管我见过很多人都有我的问题,似乎没有一个通用的解决方案。最好的解决方案是将for循环体转换为一个函数,然后调用该函数,但这个解决方案对我来说还不够好。

所以我想知道,OpenMP有一个#if(expression) else类型的pragma?比如:

#if(isDynamic )pragma omp parallel for num_threads(thread_count) default(shared) 
private(...) schedule(dynamic, 10) 
else 
pragma omp parallel for num_threads(thread_count) default(shared) 
private(...) schedule(static)
或者我被迫将我的for循环体放入一个单独的函数中并以这种方式调用它?

这是个有趣的问题。基本上,您希望在运行时更改schedule策略。据我所知,目前的OpenMP没有这样的指令。

我有和你完全一样的问题。我的解决方案是把循环体变成一个函数,正如你提到的。否则,您需要使用一个难看的宏。

然而,我也尝试使用schedule(runtime),它读取环境变量OMP_SCHEDULE。所以,我在运行时改变了这个环境变量,但是没有成功。这是因为OpenMP运行时在开始时只读取此环境一次。这可能是特定于实现的问题。因此,其他实现可能会动态地读取这个环境变量。你可以试试这个方法

这已经迟了好几年了,但是对于这种特殊情况,您可以使用运行时库在运行时设置计划。它在OpenMP 4.5的§3.2.12中定义:

void omp_set_schedule(omp_sched_t kind, int chunk_size);
typedef enum omp_sched_t {
    omp_sched_static = 1,
    omp_sched_dynamic = 2,
    omp_sched_guided = 3,
    omp_sched_auto = 4
} omp_sched_t;

对于你的例子,你要做的是:

/* wherever currently isDynamic is set */
if (isDynamic) {
    omp_set_schedule(omp_sched_dynamic, 10);
} else {
     /* chunk_size < 1 uses default */
    omp_set_schedule(static, 0);
}
/* later */
#pragma omp parallel for num_threads(thread_count) default(shared) private(...) schedule(runtime)
for (...) {
   /* do a thing */
}