【发布时间】:2016-03-20 07:18:19
【问题描述】:
我正在尝试使用 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 编译错误:
错误 #8592:在 SIMD 区域内,不得在 PRIVATE SIMD 子句中指定 DO 循环控制变量。 [换档]
在网上查找,我找不到任何成功解决此问题的方法。在我看来,ishift 应该是私有的,但编译器不允许这样做。内部循环变量是否自动强制为私有?
后续问题:稍后,当我在iy 循环周围添加omp parallel do 时,我应该在omp parallel do 指令、omp simd 指令中包含private(ishift) 子句还是两者都包含?
感谢您的澄清。
【问题讨论】:
-
针对常见情况展开专门化的循环。
-
简单的
omp simd构造不是多线程的,它们是不同的向量化的。您保留循环的主体,但将标量指令替换为向量指令。如果您尝试自己手动编写此矢量化版本,您会立即明白为什么将ishift设为私有毫无意义。 -
谢谢@Gilles。我已经知道你在说什么,但强迫自己试着写出来真的让我更好地理解它,并使你的观点非常明显。你是对的 -
ishift变量不应设为私有。此外,我想不出应该将循环迭代器设为私有的情况,因此 ifort 错误对我来说似乎是合理的。干杯。 -
我明白我一开始的问题是错的。我以为你在
iy循环周围有omp do private(ishift)。在这种情况下,私人应该不是问题。
标签: fortran openmp vectorization simd