什么是最好的计算方法:
在哪里是对角线并且很一般。我最感兴趣的是这两种情况:
- ,
- ,
选项
我可以想到四种没有明显缺陷的方法:循环、forall、zgbmv上的循环、 zdscal上的循环。
环形
do i = 1,n
do j = 1,m
Y(j,i) = D(j) * X(j,i)
enddo
enddo
- 优点:易于阅读,按顺序读取 D、X、Y
- 缺点:不重复使用 D
对所有人
forall (i = 1:n, j = 1:m) Y(j,i) = D(j) * X(j,i)
zgbmv
Dz = cmplx(D)
do i = 1,n
call zgbmv('N', m, m, 0, 0, one, D, 1, X(1,i), 1, zero, Y(1,i), 1)
enddo
- 优点:类似于循环,但可能包含 BLAS 魔法
- 缺点:不重复使用 D,通过强制转换为复杂的 D 大小加倍
zdscal
Y = X
do i = 1,m
call zdscal(n,D(i),Y(i,1),m)
enddo
- 优点:重复使用 D,可能包含 BLAS 魔法
- 缺点:跨步读取 Y,如果不是就地需要复制
想法
两个主要的权衡似乎是顺序读取 X 与重用 D 和使用 fortran 库与将 D 视为真实而不是转换为复杂。在这两种情况下,自定义实现都可以两全其美,但我对特定于架构的参数持怀疑态度。最好的情况是本机表达操作(例如循环或forall)并告诉编译器完成其余操作。