在平坦的fortran矩阵上循环

时间:2013-01-21 14:57:05

标签: vectorization fortran90 loop-unrolling

我有一些看起来像这样的代码:

DO I=0,500
    arg1((I*54+1):(I*54+54)) = premultz*sinphi(I+1)
ENDDO

简而言之,我有一个维54的数组前置。我有一个维数为501的数组sinphi。我想取sinrc的第一个值乘以premultz的所有条目并将其存储在arg1的前54个条目中,然后sinphi的第二个值乘以premultz的所有条目并将其存储在arg1的second54条目中,依此类推。

这些是扁平矩阵。为了速度,我把它们弄平了,因为这个项目的主要目标之一就是代码非常快。

我的问题是:在Fortran90中有更有效的编码方式吗?我知道Fortran有很多漂亮的数组操作可以完成,我还没有完全清楚。

提前致谢。

1 个答案:

答案 0 :(得分:0)

如果我说得对,这个表达式应该在一个陈述中创建arg1

arg1 = reshape(spread(premultz,dim=2,ncopies=501)*&
              &spread(sinphi,dim=1,ncopies=54),[1,54*501])

我已经在这里修改了尺寸,这可能适用于您的目的,也可能不适合您的目的。内部表达式生成premultzsinphi的外积,然后将其重新整形为向量。您可能会发现需要重塑外部产品的转置,我没有仔细检查过。

然而,根据我对Fortran阵列内在函数的这种巧妙使用的经验,我怀疑这个或者Fortran的数组内在函数的其他大多数巧妙用法都会胜过你已经拥有的直接循环实现。对于许多这些操作,编译器将生成数组的副本,并且复制数据相对昂贵。当然,这是一个你可能想要测试的断言。

我会留给你来决定单行是否比循环更容易理解。有时,数组语法的表达性在性能上是可接受的成本,有时则不然。