我正在尝试使用OpenMP 4.0的simd
特性对嵌套循环进行向量化,但我担心我的操作不正确。我的循环如下:
do iy = iyfirst, iylast
do ix = ixfirst, ixlast
!$omp simd
do iz = izfirst, izlast
dudx(iz,ix,iy) = ax(1)*( u(iz,ix,iy) - u(iz,ix-1,iy) )
do ishift = 2, ophalf
dudx(iz,ix,iy) = dudx(iz,ix,iy) + ax(ishift)*( u(iz,ix+ishift-1,iy) - u(iz,ix-ishift,iy) )
enddo
dudx(iz,ix,iy) = dudx(iz,ix,iy)*buoy_x(iz,ix,iy)
enddo
!$omp end simd
enddo
enddo
请注意,
ophalf
是一个小整数,通常为2或4,因此向量化iz
循环而不是最内层循环是有意义的。我的问题是:我是否需要将
ishift
标记为私有变量?
在标准的OpenMP parallel do
循环中,确实需要使用private(ishift)
来确保其他线程不会覆盖彼此的数据。但是,当我将第一行重写为!$omp simd private(ishift)
时,我得到了ifort编译错误:
在线上搜索后,我没有找到任何成功解决这个问题的方法。对我来说,error #8592:在SIMD区域内,DO-loop控制变量不能在PRIVATE SIMD子句中指定。[ISHIFT]
ishift
应该是私有的,但编译器不允许它。内部循环变量是否自动强制为私有?后续问题:稍后,当我在
iy
循环周围添加omp parallel do
时,我应该在omp parallel do
指令、omp simd
指令或两者都包含private(ishift)
子句吗?感谢任何澄清。
omp simd
结构不是多线程的,而是矢量化的,这是不同的。您保留循环体,但将标量指令替换为矢量指令。如果您尝试手动编写此矢量化版本,您会立即看到为什么使ishift
私有化没有太大意义。 - Gillesishift
变量不应该被设为私有。此外,我想不出一个情况,循环迭代器应该被设为私有,所以ifort错误对我来说似乎是合理的。干杯。 - NoseKnowsAlliy
循环周围有omp do private(ishift)
。在这种情况下,私有变量不应该是一个问题。 - Vladimir F Героям слава