0

我有一个问题,它涉及使用一个小的 2 级数组(下面的代码中的 array2)来保存一个更大的 4 级数组(下面的 array1)的一些元素的有序列表。目前,我的一个步骤涉及使用 DO 循环,我想知道是否可以使用某种“数组到数组”操作一步完成?在我正在编写的主要代码中,我发现尽可能使用这种“数组到数组”操作可以显着提高速度。我觉得这是一个简单的问题,但我看不到解决方案或在网上找到解决方案。我将不胜感激任何帮助!以下代码是问题的简化模型,但包含基本特征。谢谢。

PROGRAM vec_array

IMPLICIT none

INTEGER :: i,j,k,l,cnt
INTEGER :: array1(-1:1, -2:2, -2:2, 3:6)
INTEGER :: array2(5,4)

! Set up arbitrary array of values in 'large' array
cnt=0
DO i=-1,1,1
  DO j=-2,2,1
    DO k=-2,2,1
      DO l=3,6,1

        cnt=cnt+2*l
        array1(i,j,k,l)=cnt

      END DO
    END DO
  END DO
END DO

! array2 holds an ordered list of array1 elements 
array2(1,:)=[-1, 2,-2, 6]
array2(2,:)=[ 0, 1, 2, 3]
array2(3,:)=[-1,-2,-2, 4]
array2(4,:)=[ 1, 2, 2, 5]
array2(5,:)=[-1,-2,-2, 3]

! This is the key step here - is there another way to do this, 
! potentially faster, that does not involve a DO-loop?
DO i=1,5,1
  array1( array2(i,1),array2(i,2),array2(i,3),array2(i,4) )=i
END DO

DO i=-1,1,1
  DO j=-2,2,1
    DO k=-2,2,1
      DO l=3,6,1

        WRITE(*,*) i,j,k,l,array1(i,j,k,l)

      END DO
    END DO
  END DO
END DO

END PROGRAM
4

1 回答 1

0

一点:我认为您的真正问题要大得多?这些微小的数组将适合缓存的最小圆圈,我认为您无法通过花哨的代码重写获得更多性能。如果它更大,你真的需要在花费太多时间重写代码以提高速度之前对代码进行分析以找到瓶颈。

需要注意的一件事,也许也有点离题,是您按 C 顺序嵌套循环(其中内存中彼此接近的数据仅在最后一个索引中不同)。但 Fortran 以相反的方式组织其数组,其中内存中彼此接近的数据仅在第一个索引上有所不同。您当前的组织方式array1是最糟糕的方式,其中最内层的循环涉及内存中最大的进步。养成排列数据和嵌套循环以尽可能多地访问连续内存的习惯是很好的。

于 2014-03-06T23:32:20.467 回答