Хорошо, дело полузакрытое. Решение оказалось довольно простым. Вы просто используете указатели и делаете assume_aligned
для них. Это должно позаботиться об этом.
type foo
real, allocatable, dimension(:) :: bar1, bar2
!dir$ attributes align:64 :: bar1
!dir$ attributes align:64 :: bar2
end type foo
type(foo), target, allocatable, dimension(:) :: my_foo
real, pointer, contiguous :: pt_bar1(:)
real, pointer, contiguous :: pt_bar2(:)
allocate(my_foo(1))
allocate(my_foo(1)%bar1(100))
allocate(my_foo(1)%bar2(100))
pt_bar1 = my_foo(1)%bar1
pt_bar2 = my_foo(1)%bar2
!dir$ assume_aligned pt_bar1:64, pt_bar2:64
pt_bar1 = 10.
pt_bar2 = 10.
do
петли все еще не векторизованы. Как если бы я сделал то же самое, как это
do i = 1, 100
pt_bar1(i) = 10.
pt_bar2(i) = 10.
end do
оно не будет векторизовано.
UPD.
Хорошо, это делает работу (также необходимо добавить флаг -qopenmp-simd
в компилятор):
!$omp simd
!dir$ vector aligned
do i = 1, 100
pt_bar1(i) = 10.
pt_bar2(i) = 10.
end do
Также, если вы просматриваете my_foo(j)%...
, обязательно освобождайте указатели после каждой итерации с помощью pt_bar1 => null()
и т. Д.
PS. Спасибо BW из нашего отдела за эту помощь. :) Иногда личное общение> stackoverflow (не всегда, только иногда).