Vla*_*r F 8 fortran simd openmp
如果我理解构造的aligned子句omp simd,它指的是整个数组的对齐.
它如何用于多维数组?假设
ni = 131; nj = 137; nk = 127
!allocates arr(1:131,1:137,1:127) aligned to 64-bytes
call somehow_allocate_aligned(arr, [ni,nj,nk], 64)
!$omp parallel do collapse(2)
do k = 1, nk
do j = 1, nj
call some_complicated_subroutine(arr(:,j,k))
!$omp simd aligned(arr:64)
do i = 1, ni
arr(i,j,k) = some arithmetic expression involving arr(i,j,k)
end do
end do
end do
!$omp end parallel do
Run Code Online (Sandbox Code Playgroud)
这是指示数组对齐的正确方法,尽管内部循环的迭代开始于arr(1,j,k)?
编译器如何使用该信息推断内部循环子阵列的对齐?
如果运行时尺寸更好(比如128,128,128),性能是否重要?
这里有解释,幻灯片 160-165:http://irpf90.ups-tlse.fr/files/parallel_programming.pdf
你应该
1)对齐数组
2) 使用填充强制所有列对齐:您的第一个维度(在分配语句中指定)应该是元素数量的倍数,以达到 16、32 或 64 字节边界,具体取决于指令集。
例如,对于具有 AVX 指令集(32 字节对齐)、双精度(8 字节/元素)的 99x29x200 矩阵,您应该这样做
n = 99
l = 29
m=200
delta_n = mod(n,32/8)
if (delta_n == 0) then
n_pad = n
else
n_pad = n-delta_n+32/8
end if
allocate( A(n_pad,l,m) )
!DIR$ ATTRIBUTES ALIGN : 32 :: A
do k=1,m
do j=1,l
!$OMP SIMD
do i=1,n
A(i,j,k) = ...
end do
end do
end do
Run Code Online (Sandbox Code Playgroud)
您可以使用 C 预处理器来制作可移植代码,替换前面示例中的 32 和 8。
注意:对数组使用 B=A 等语句时要小心,因为物理维度与逻辑维度不对应。好的做法是将边界设置为 B(1:n,1:l,1:m) = A(1:n,1:l,1:m),因为如果更改物理尺寸,它仍然有效。
| 归档时间: |
|
| 查看次数: |
1282 次 |
| 最近记录: |