Fortran 循环未矢量化,因为它包含对非矢量内在函数的引用

Fortran 循环未矢量化,因为它包含对非矢量内在函数的引用,fortran,vectorization,Fortran,Vectorization,我正在编写一个大型Fortran程序,其中性能至关重要。我使用模块来存储公共参数和变量。但问题是,如果模块变量用于某种数组操作,编译器就不会对其进行矢量化。以此为例, module name integer :: p end module name program name1 use name real(kind=8) :: x(10,10), y(10) integer :: i,j p=9 do i=1,10 do

我正在编写一个大型Fortran程序,其中性能至关重要。我使用模块来存储公共参数和变量。但问题是,如果模块变量用于某种数组操作,编译器就不会对其进行矢量化。以此为例,

module name
    integer :: p    
end module name


program name1
    use name
    real(kind=8) :: x(10,10), y(10)
    integer :: i,j 
    p=9
    do i=1,10
        do j =1,10
            x(i,j) = i+j
        enddo
    enddo

    y = x(:,p)*x(:,p-1)
    print *, y
end program name1
现在,当我使用
ftn-eD file.f90
Cray(XC50)
上编译它时,生成的
.lst
文件显示

   9.    program name1
   10.        ! implicit none
   11.        use name
   12.        real(kind=8) :: x(10,10), y(10)
   13.        integer :: i,j
   14.        do i=1,10
   15.            do j =1,10
   16.                x(i,j) = i+j
   17.            enddo
   18.        enddo
   19.
   20.        y = x(:,p)*x(:,p-1)
ftn-6263 ftn: VECTOR NAME1, File = test.f90, Line = 20
  A loop starting at line 20 was not vectorized because it contains a reference to a non-vector intrinsic on line 20.

   21.        print *, y
   22.    end program name1
   23.
   24.

我一直认为使用
执行数组操作会更容易让编译器将其矢量化。但若使用模块变量不利于矢量化,那个么在性能至关重要时使用模块是否也不好呢?我是不是弄糊涂了?如何提高这些情况下的性能?

您可以通过执行类似于
y=dot_乘积(x(:,p-1),x(:,p))
的操作来强制编译器对您的操作进行向量化吗?好的,现在它显示
从第20行开始的循环已部分向量化。
如果您的CPU具有4/8通道SIMD 64位浮点操作功能,大小为10的数组无法完全矢量化,因此编译器可能会将范围[1:4]和[5:8]作为SIMD运行,而元素9和10将是串行代码。另外:我注意到您没有计算点积,所以我以前的评论不是对您原始代码的有效替换。一种选择是尝试对所有(i=1:10)y(i)=x(i,p)*x(i,p-1)进行
,或者类似地,对于
do concurrent
,上面的例子非常简单。实际的操作可能更大更复杂,我有数千个这样的操作。那么,在这种情况下,你最后会建议遵循什么?(可能你可以在这里输入答案。)它可能已经决定不进行矢量化,因为矢量长度很短。如果你让它变长会发生什么?如果长度作为参数传递给子程序,会发生什么情况?