【发布时间】:2017-01-27 05:58:33
【问题描述】:
我正在编写性能密集型 Fortran 代码,它的核心是一个无矩阵矩阵乘法子例程 mfmult(x,y),它接受一个输入向量 x,并返回一个输出向量 y,如果 i = i_{n-1}i_{n-2}...i_2i_1i_0 是一个 n 位二进制数(可能带有前导零),那么
y(i) = sum{x(j) : j 是 i 的任何 1 位否定}
即
y(000) = x(001)+x(010)+x(100)
y(1101) = x(0101)+x(1001)+x(1111) + x(1100) etc.
什么是实现这一点的有效方法?一个相关的问题是:Fortran 中是否存在用于单位否定的快速内在函数?我看过内在函数和https://rosettacode.org/wiki/Bitwise_operations#Fortran,但没有单位否定操作,我担心任何手动编码/分支语句都会让事情变得太慢。
【问题讨论】:
-
好吧,无论如何,CPU 总是访问整个字节。您可以使用 IBSET(),但我不希望它特别有效。您还可以将 IEOR() 与某些特定常量一起使用。
-
IBSET 和 IBCLR 的问题是我首先需要一个 BTEST if 语句来检查该位是否为 0 和 1,以便我可以选择相反的,我希望它在一个巨大的环形。我不确定如何使用 IEOR()。翻转一个位似乎是一种基本操作,以至于这些方法似乎有点矫枉过正。这是否只是 Fortran 作为一种语言的限制,它没有这种内在特性?
-
如果您想将其称为限制...您认为 Fortran 中缺少 C 或 x86 程序集的等效项是什么?
-
谢谢,IEOR 方法运行得非常快。事实上,我很惊讶地发现它比使用稀疏矩阵显式地执行向量转换更快(大约快两倍)。在做了更多研究之后,我现在看到其他语言也只是使用这种方法进行位否定。