背景
我使用了很多位运算,但我甚至不知道它们在最低级别是如何实现的。
我想看一下英特尔/AMD开发人员如何实现这些操作。 不是为了在我的代码中替换它们,那样会很愚蠢... 而是为了更广泛地了解正在发生的事情。
我试图找到一些信息,但大多数时候,人们询问其用途或用其他位运算替换它,但这里并非如此。
问题
它是否在汇编(SSE)中对32位进行基本迭代和比较?
有没有一些技巧可以加快速度?
谢谢
绝大部分都是作为基本的本地指令直接在CPU上实现,而不是SSE的一部分。这些是CPU寄存器上最古老、最基本的操作。
至于如何实现and、or、xor等操作,如果你真的有兴趣,可以查阅数字逻辑设计或离散数学。查找Flip-flops、AND门或NAND/NOR/XOR门。
https://en.wikipedia.org/wiki/NAND_logic
还可以查阅K-map(卡诺图),这是你可以手动实现逻辑电路的方法。
https://en.wikipedia.org/wiki/Karnaugh_map
如果你真的喜欢阅读,可以在有工程或计算机科学大学资源的前提下报名数字逻辑设计课程。你将能够在面包板上使用大型集成电路构建逻辑电路,但现在大多数CPU都像软件一样通过代码编写并打印在硅晶圆上。
特别值得关注的是NAND和NOR,因为它们具有功能完备性(可以使用NAND或NOR构造任何真值表)。
NAND(逻辑符号看起来像=Do-)
A
=Do- Q is Q = NOT(A AND B)
B
Truth table
A B Q
0 0 1
0 1 1
1 0 1
1 1 0
使用NAND门可以重写任何逻辑。
正如您所看到的,它非常高效,使用二进制无法获得更低级别的单个门电路(虽然存在三进制/三态逻辑),因此它只需要一个时钟状态变化。 因此,对于一个64位CPU寄存器,您将需要在寄存器旁边放置64个这些"宝贝",每个核心...每个指令。 而这仅仅是“逻辑”寄存器。因为先进的处理器(如Intel Core)进行寄存器重命名,所以在硅上存在比名称逻辑上可用的寄存器更多的物理寄存器。
按位操作是处理器的组成部分,因此自然要用指令来公开这些操作。像AND、OR、XOR、NOR、NAND和NOT这样的操作可以通过每位ALU只有几个逻辑门来执行。重要的是,结果的每个比特只依赖于输入的两个比特(不像乘法或加法),因此整个操作可以并行进行,没有任何复杂性。
正如您所知,计算机中的数据以二进制格式表示。
例如,如果您有整数13,则表示为1101b
(其中b
表示二进制)。这相当于(1) * 8 + (1) * 4 + (0) * 2 + (1) * 1 = 13
,就像(1) * 10 + (3) * 1 = 13
一样--不同的进制。
然而,对于基本操作,计算机需要知道您正在处理多少数据。典型的整数大小为32位。因此,它不仅是1101b
,而且是00000000000000000000000000001101b
--32位,其中大部分未使用。
按位运算就是这样--它们仅在位级别上进行操作。加法、乘法和其他操作考虑多个位来执行其功能,但按位运算符不会。例如:
12按位与7是多少?(在C语言中,12 & 7
)
1010b 12 &
0111b 7
----- =
0010n 2
为什么?垂直思考!看左边的数字集合——1和0是0。然后,0和1是0。接着,1和1是1。最后,0和1是0。
这基于“与”真值表规则——只有真(即1)和真(即1)才会得到假(即0)。所有其他结果都是假(即0)。
同样地,“或”真值表规则指出,除了假(即0)和假(即0)得到假(即0)外,所有结果都是真(即1)。
让我们做同样的例子,但这次让我们计算12按位或7。(在C语言中,12 | 7
)
1010b 12 |
0111b 7
----- =
1111n 15
~7
)0111b ~7
----- =
1000b 8
等等..那些前导零呢?嗯,是的,在此之前我省略了它们,因为它们并不重要,但现在它们肯定很重要:
00000000000000000000000000000111b ~7
--------------------------------- =
11111111111111111111111111111000b ... big number?
如果您指示计算机将结果视为无符号整数(32位),那么这是一个非常大的数字(略小于40亿)。如果您指示计算机将结果视为带符号整数(32位),那么结果为-8。
正如您可能已经猜到的那样,由于所有这些操作的逻辑非常简单,因此您不能做太多事情来使它们单独更快。但是,按位操作遵循布尔逻辑相同的逻辑,因此您可以使用布尔逻辑缩减技术来减少可能需要的按位操作数量。
例如:(A & B) | (A & C)
的结果与 A & (B | C)
相同。
然而,这是一个更大的话题。卡诺图是一种技术,但boolean algebra通常是我在编程时使用的技术。
a = b & c;
这样的一行代码可能会有一个直接的机器指令或两个指令来执行它,而不太可能有任何技巧使其更快。 - chux - Reinstate Monica