两次使用不同配置循环1D

时间:2016-08-29 11:37:05

标签: fortran vectorization gfortran intel-fortran

有谁知道,为什么Program BProgram A更快?

我将ifort-16-fast优化标记结合使用,优化报告称Program A估计潜在加速速度为10.09,而Program B仅为3.90。但是,实际上Program B的运行时间是14秒,而Program A的运行时间是20秒。

!Program A
 DO J=1, 100000          !This is the different part
   !$OMP SIMD
    DO I=1, 100000
       IF(A(I)==J) THEN
          B(I)=J
       END IF          
    END DO
   !$OMP END SIMD
 END DO

!Program B
 DO I=1, 100000          !This is the different part
   !$OMP SIMD
    DO J=1, 100000
       IF(A(I)==J) THEN
          B(I)=J
       END IF          
    END DO
   !$OMP END SIMD
 END DO   

嗯,两个程序都成功地进行了矢量化,不知怎的,我感觉program A会更快,因为(在我看来),两个代码都会被矢量化如下:

!Program A
 IF(A(I)==J) THEN
    B(I)=J
 END IF

 IF(A(I+1)==J) THEN
    B(I+1)=J
 END IF

... 

!Program B
 IF(A(I)==J) THEN
    B(I)=J
 END IF

 IF(A(I)==J+1) THEN
    B(I)=J+1
 END IF

... 

其中Program A将更有效,因为左侧索引是直接计算的。但事实上,我的期望是错误的。提前致谢。

1 个答案:

答案 0 :(得分:1)

程序的运行时间包括许多组件。我们大多数时间看的是计算时间。但是,我们还有内存访问权限,这是大多数程序的瓶颈。还有其他组件,但我将自己局限于这两个。 在您的情况下,内存访问可能会产生重大影响。

在程序B中,运行J的内部循环(带有100000索引)在外部循环的每次迭代中访问相同的内存空间A(I)B(I)I索引)。一旦将它们加载到寄存器中,就不再需要进入存储器了。只有当外部循环的索引I发生变化时,程序才会进入内存。那是100000

在程序A中,运行I的内部循环(带有100000索引)在内部循环的每次迭代中访问不同的内存位置A(I)B(I)。由于您无法在寄存器中使用100000,因此CPU必须等待数据。由于外部循环(J索引)也运行100000次,因此程序A的100000x100000内存访问权限与程序B的100000相比。

这是你观察到的一种可能的解释。