我目前正在尝试使用OpenMP并行化一些用Fortran编写的多重网格代码,我发现OpenMP调度子句对性能产生了巨大影响。回想一下,OpenMP调度子句是静态的,动态的,运行时的和引导的,它们决定了循环中的工作如何在线程之间划分。例如,带有调度子句的OpenMP并行化SAXPY循环如下所示:
!$OMP Parallel Do Schedule(Static)
Do i=1,n
z(i)=a*x(i)+y(i)
End Do
!$OMP End Parallel Do
现在假设我们在一段代码中有许多并行化循环,并且无法确定先验这些调度子句中的哪一个将使程序运行得最快。手动更改每个调度条款将是一个痛苦的屁股,所以这就是我认为我会做的:
Character(Len=10)::sched="Dynamic"
!$OMP Parallel Do Schedule(sched)
Do i=1,n
z(i)=a*x(i)+y(i)
End Do
!$OMP End Parallel Do
然后我可以简单地将该字符变量'sched'放在每个并行循环中并立即更改它们,例如,将sched =“Static”,然后进行运行时测试以查看哪一个最快!当然,它不起作用 - 至少不能用gfortran或Absoft编译器。所以我的问题是以下任何一个或全部:为什么这不起作用?,我怎样才能使它工作?或者我怎样才能避免使用这个结构来解决这个问题?非常感谢任何帮助。
答案 0 :(得分:2)
这不起作用,因为模式不是真正的字符串,并且此时没有进行变量评估,我想。我能想到的最好的事情是使用像CoCo这样的预处理器或C-Preprocessor来实现这一点。 但是,您也可以使用运行时模式并使用环境变量OMP_SCHEDULE或omp_set_schedule例程来设置模式。
答案 1 :(得分:0)
您指定的调度子句将对循环编译为机器代码的方式产生巨大影响。编译代码后,调度模式将被锁定,无法在运行时更改。我同意haraldkl,使用预处理器。