我正在快速掌握矢量化,因为我目前的PC支持它。我有英特尔i7-7600u。它有2个内核,运行频率为2.8 / 2.9 GHz,支持SSE4.1,SSE4.2和AVX2。我不确定向量寄存器的大小。我相信它是256位,因此一次可以使用4个64位双精度值。我相信这应该给出一个高峰率: (2.8GHz)(2个核心)(4个向量)(2个/多个)= 45个GFlops。 我正在使用GNU Gfortran和g ++。
我在制作各种超级计算机的过程中建立了一系列的fortran循环。 我测试的一个循环是:
do j=1,m
s(:) = s(:) + a(:,j)*b(:,j)
enddo
向量长度为10000,m = 200,并且执行嵌套500次以进行2e9操作。我用j循环展开它,展开0,1,2,3和5次。展开应减少加载和存储的次数。它也是最佳的,因为所有的内存访问都是跨步的,它有一个成对的加法和乘法。我使用如上所示的数组语法和使用内部do循环运行它,但这似乎没什么区别。使用do循环并且不展开它看起来像:
do j=1,m
do i=1,n
s(i)=s(i)+a(i,j)*b(i,j)
end do
end do
构建如下:
gfortran -O3 -w -fimplicit-none -ftree-vectorize -fopt-info-vec loops.f90
编译器说循环都是矢量化的。我得到的最好结果是2.8 GFlops,每个周期一个。如果我用:
运行它gfortran -O2 -w -fimplicit-none -fno-tree-vectorize -fopt-info-vec loops.f90
未报告任何矢量化。它在不展开的情况下执行速度稍慢,但与展开相同。谁能告诉我这里发生了什么?我的处理器特性是否错误?为什么矢量化不会加快速度?我期待得到至少一些改善。如果这会让人感到遗憾,我会道歉,但我找不到类似于此的干净例子。