Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Optimization Fortran:有效的矩阵向量乘法_Optimization_Fortran_Matrix Multiplication_Blas - Fatal编程技术网

Optimization Fortran:有效的矩阵向量乘法

Optimization Fortran:有效的矩阵向量乘法,optimization,fortran,matrix-multiplication,blas,Optimization,Fortran,Matrix Multiplication,Blas,我有一段代码是一个重要的瓶颈: do s = 1,ns msum = 0.d0 do k = 1,ns msum = msum + tm(k,s)*f(:,:,k) end do m(:,:,s) = msum end do 这是每个x,y的简单矩阵向量积m=tm*f(其中f是长度k) 我考虑过使用BLAS例程,但我不确定是否有允许沿特定维度进行乘法的例程(k)。你们有什么好的建议吗?不幸的

我有一段代码是一个重要的瓶颈:

    do s = 1,ns
        msum = 0.d0
        do k = 1,ns
            msum = msum + tm(k,s)*f(:,:,k)
        end do
        m(:,:,s) = msum
    end do
这是每个
x,y
的简单矩阵向量积
m=tm*f
(其中
f
是长度
k


我考虑过使用BLAS例程,但我不确定是否有允许沿特定维度进行乘法的例程(
k
)。你们有什么好的建议吗?

不幸的是,你们没有提到
f
的实际形状,即
x
y
的数量。由于您提到这段代码是一个瓶颈,因此您可以而且应该替换
msum
,并使用内存
m(:,:,s)
,并节省循环中的第一步,例如

do s = 1,ns
    m = tm(k,1)*f(:,:,k)
    do k = 2, ns
        m(:,:,s) = m(:,:,s) + tm(k,s)*f(:,:,k)
    end do
end do
第二,更一般的方法
通过存储在
tm(:,1:ns)
中的标量因子,存在
ns
nK
2D矩阵
f(:,:,1:nK)
。目标是将这些总和存储在
m(:,:,1:ns)
中。为什么不将元素wrt
x
y
相加,利用结果利用相邻的内存段呢?您已经提到,您可以重新设计
k
f
中的第一个维度,即
f(k,:,:)

仅考虑期望的结果,您应该拥有相互独立的
ns
2D矩阵
m(:,:,1:ns)
(外部循环保持不变)。让我们暂时放下这个维度。问题就变成了:

m(:,:)=\sum{k=1}^{ns}tm_k*f_k(:,:)

因此,我们应该对
k
求和,例如,用
f(k,:,:)
来确定
m(:,:)
,如下所示(注意,我再次为
s
添加了外循环):

有关其用法的详细信息,请参阅的文档


当然,上述排除循环的第一步以通过零来避免初始化的建议也可以很好地应用。

你能重新设计
f
,使
k
成为第一维度吗?是的,我能,这相对容易,但是数据在内存中是不连续的,非常有趣!我会实施,看看是否有任何改进。既然你问了,x,y的大小取决于域的大小,但现在假设它们固定在100。k的大小固定为9。@nLoije关于x和y的大小:取决于通过BLAS的实际速度(或者更确切地说,使用OpenBLAS,速度更快!),重新排列维度可能会或可能不会提高算法的整体速度。然而,这是特定于您的问题和代码的,应该值得测试。
nK = size(f, 1)  ! the "k"s
nX = size(f, 2)  ! the "x"s
nY = size(f, 3)  ! the "y"s
m = 0.d0
do s = 1, ns
    do ii = 1, nY
        call DGEMV('N', nK, nY, &
                   1.d0, f(:,:,nY), 1, tm(:,s), 1, &
                   1.d0, m(:,nY,s), 1)
    end do !ii
end do !s