Fortran 是否有更有效的方法从单个大型一维阵列收集元素,并将它们放置在单个小型一维阵列中?
简单描述:我有一个大数组(数据类型为real64)Fortran 是否有更有效的方法从单个大型一维阵列收集元素,并将它们放置在单个小型一维阵列中?,fortran,vectorization,fortran90,intel-fortran,Fortran,Vectorization,Fortran90,Intel Fortran,简单描述:我有一个大数组(数据类型为real64)bigArray1,它是以不排序的方式用数字分配和初始化的。我创建了另一个小数组smallArray,其数据类型与大数组相同。 现在,我希望smallArray根据掩码(比如bigArray1>0.0d0)包含bigArray1的子集。这一点很容易通过固有的: smallArray = pack(bigArray1, bigArray1 > 0.0d0) 现在,更进一步,假设我有另一个bigArray2,我想smallArray在bigA
bigArray1
,它是以不排序的方式用数字分配和初始化的。我创建了另一个小数组smallArray
,其数据类型与大数组相同。
现在,我希望smallArray
根据掩码(比如bigArray1>0.0d0
)包含bigArray1
的子集。这一点很容易通过固有的:
smallArray = pack(bigArray1, bigArray1 > 0.0d0)
现在,更进一步,假设我有另一个bigArray2
,我想smallArray
在bigArray1
上的掩码和bigArray2
上的不同掩码的交集返回的索引中从bigArray1提取元素,我可以做:
smallArray = pack(bigArray1, bigArray1 > 0.0d0 .and. bigArray2 < 0.0d0)
带do循环:
program test
use, intrinsic :: iso_fortran_env
integer, parameter :: dp = real64
real(dp), allocatable :: a(:), b(:), c(:)
!dir$ attributes align:64 :: a
!dir$ attributes align:64 :: b
!dir$ attributes align:64 :: c
allocate(a(1:10), b(1:10))
a = [1.1_dp, 1.2_dp, 1.3_dp, 1.4_dp, 1.5_dp, 1.6_dp, 1.7_dp, 1.8_dp, 1.9_dp, 2.0_dp]
b = [2.1_dp, 2.2_dp, 2.3_dp, 2.4_dp, 2.5_dp, 2.6_dp, 2.7_dp, 2.8_dp, 2.9_dp, 3.0_dp]
write(*,*) 'a :', a
write(*,*) 'b :', b
c = pack(a, a >=1.2_dp .and. a < 1.9_dp .and. b >=2.3_dp .and. b < 2.6_dp )
write(*,*) 'c :', c
deallocate(a,b,c)
end program test
!Initialize number of elements in c to 0
n_elem_c = 0
!Count elements that satisfy both masks
do i = 1, 10
if(a(i) >= 1.2_dp .and. a(i) < 1.9_dp &
.and. b(i) >= 2.3_dp .and. b(i) < 2.6_dp) then
n_elem_c = n_elem_c + 1
end if
end do
allocate(c(1:n_elem_c))
id = 0
!Assign elements to c
do i = 1, 10
if(a(i) >= 1.2_dp .and. a(i) < 1.9_dp &
.and. b(i) >= 2.3_dp .and. b(i) < 2.6_dp) then
id = id + 1
c(id) = a(i)
end if
end do
a : 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2.0
b : 2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9 3.0
c : 1.3 1.4 1.5
有没有一种可以矢量化的替代算法?也许更快?还是这是唯一可行的方法
我希望我能解释我的问题。到目前为止,我一直是stackoverflow的搜索者,这是我的第一个问题,所以我谦恭地请求领主们对我温和一点。如果您需要此算法的实际用例,我可以提供代码片段。您关心并行化吗?或者这与可能包括并行化的其他工作无关?实际上,这个代码片段是在
中调用的子程序的一部分$omp并行do计划(运行时)
区域。所以我希望它被矢量化,以利用内核中的矢量寄存器。bigArray1
和bigArray2
是否被约束为具有相同的大小-这似乎是您向我们展示的示例代码的必然结果?如果是这样的话,您可以通过将代码转换为秩2数组并小心排序来实现更方便缓存的代码。@HighPerformanceMark YesbigArray1
和bigArray2
的大小始终相同。请原谅我的理解,你能详细说明你的建议吗?