如果我理解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
这是指示数组对齐的正确方法,尽管内循环的迭代从arr(1,j,k)
开始?
编译器如何使用该信息推断内部循环子阵列的对齐?
如果运行时尺寸更好(例如128,128,128),性能是否重要?
答案 0 :(得分:1)
这里解释了幻灯片160-165:http://irpf90.ups-tlse.fr/files/parallel_programming.pdf
你应该
1)对齐数组
2)使用填充强制所有列对齐:您的第一个维度(在allocate语句中指定)应该是到达16,32或64字节边界的元素数量的倍数,具体取决于指令集。
例如,对于具有双精度(8字节/元素)的AVX指令集(32字节对齐)的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
您可以使用C预处理器来替换上一个示例中的32和8的可移植代码。
注意:请小心使用B = A等语句作为数组,因为物理尺寸与逻辑尺寸不对应。好的做法是将边界设置为B(1:n,1:l,1:m)= A(1:n,1:l,1:m),因为如果更改物理尺寸,它仍然可以工作。 / p>