Fortran中的高效单比特否定

Par*_*dox 1 binary fortran bit

我正在编写性能密集型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.
Run Code Online (Sandbox Code Playgroud)

实现这一目标的有效方法是什么?一个相关的问题是:Fortran中是否存在快速内在的单位否定?我已经看过内在函数和https://rosettacode.org/wiki/Bitwise_operations#Fortran,但是没有单位否定操作,我担心任何手动编码/分支语句都会使事情变得太慢.

Vla*_*r F 5

我建议你使用IEOR()内在的.你必须先准备好正确的面具.它似乎是间接的,但我认为事实上还没有更直接的东西,参见C /汇编:如何更改CPU寄存器中的单个位?

所以如果你有整数i,并且想要翻转第三位,我会真的这样做:

i = ieor(i, int(b'00000100'))
Run Code Online (Sandbox Code Playgroud)

这将在x86_64程序集中做什么

xorl    $4, the_register_holding_i
Run Code Online (Sandbox Code Playgroud)

如果要在该整数中翻转多个位,最好相应地准备掩码并调用IEOR()一次.

请注意,CPU始终使用整个字节(至少)或使用整个字更有效地工作,没有指令只接受一个位的地址并仅操作那个.您不必担心您正在访问整个32位整数,因为您有32位或64位处理器.指令集准备好有效地使用32位和64位整数.