NSA教学

2021-06-11 17:23:04

今天使用的大多数CPU架构都有一个名为Popcount的指令,即“人口计数”。这是它的所作所为:它计算了机器字中的设置位的数量。例如(假设用于简单的8位字),Popcount(00100110)为3并且PopCount(01100000)是2。

你可能想知道,就像我一样,如果这条指令有更多的话,那就是它所做的一切!这似乎并不是很有用,对吗?

我认为这可能是一些高超专业的用例的添加,但它实际上已经存在于自1961年以来的CPU架构中:

PopCount也称为“NSA指令”,并且Comp.arch上的非常有趣的线程讨论其在内部和外部密码内容中。据传,它最初被添加到NSA的CPU指令中。由于此归档的电子邮件线程将其放置:

这几乎是一个传统,其中一个新的CDC机器中的第一个被交付给“好客户” - 由匿名卡车在工厂拾取,从未再次听过。

信息内容的一个度量是汉明权重,这是与字母零符号不同的字符串中的符号数。对于二进制字符串,这正是opcount!

如在这里解释的,NSA想在截获的消息上进行密码分析,并且由于CDC 6000有60位的单词,一个字就足以存储他们感兴趣的大多数字母。他们能够:

好奇地,PopCount似乎已经从20世纪70年代中期和2000年代中期之间的指令集中消失了,因此必须比加密应用更多地解释其返回。还有什么可以用来?

与汉明重量的概念有关是汉明距离,这是两个相同长度之间的不同位置的数量。对于两个二进制字符串x和y,这只是他们一起xored的opcount。例如:

对于电信应用,这有助于我们计算信号距离,其中已知的单词被电线发送,并计数翻转比特的数量以提供通过传输引入的误差的估计。

然后,我们可以相应地设计错误校正代码,例如,如果我们希望对最多2个翻转位的强大,我们的代码词需要在汉明距离至少5时不同。

而现在是完全不同的东西:二元卷积神经网络!但首先,他们是什么?

二进制意味着我们使用仅由值+1(编码为1)和-1(编码为0)的矩阵,而不是32位浮点值。

神经网络是由动物大脑启发的系统(我在这部分朦胧)。

总之,我们必须进行二进制矩阵乘法。但是关于二进制矩阵有什么特别之处?

32位值上的普通矩阵乘法是具有强大CPU和GPU的桌面计算机上的良好适合,但我们也想在更小型和更简单的设备上进行有用的工作,例如智能手机,路由器,智能手表等。我们可以分解这些更复杂的矩阵分成二进制矩阵层,并且这些产生的矩阵更容易存储和操作,即使有更多的层,我们也会更好。

Popcount在哪里发挥作用?它用于计算两个二进制矩阵的点乘积:

a = xnor(x,y)b = popcount(a)c = len(a)点(x,y)= 2×b - c

许多国际象棋程序使用位板表示存储数据,这方便地适合64位字。人口计数已被用来使用这种表示来执行有意义的操作,例如计算一块的移动性。

这与上面的汉明距离的概念有关:分子以某种方式散列并比较(用Popcount)来确定它们是多么相似的。有关这里的更多细节。

这是我第一次学习obcount的地方! HAMT是数据结构(Phal Bagwell开创),可以在Trie的每个节点处存储非常大的值(通常为32或64)。但是,每次可以令人难以置信的浪费,特别是,如果阵列实际上只包含少数元素,则为32或64元素阵列分配内存。该解决方案是添加一个位掩码,其中设置的位数对应于阵列中的元素的数量,其允许阵列根据需要增长和缩小。然后可以使用popcount进行有效地计算给定元素的索引。您可以了解更多有关他们如何从本博客文章工作的更多信息,我自己实施它们。

这是一个激动人心的研究领域,专注于如何将数据存储在尽可能少的空间中,而无需解压缩它以便进行有用的工作。一种技术是在比特阵列(BitVectors)方面进行思考,可以使用两个操作查询:

使这些操作在大型比特媒体上有效需要构建索引并有效地使用它,涉及Popcount。这里的RRR指数有很好的概述,据我所知,目前的最先进的方法在节省空间,高性能等级&amp中描述了;在未压缩位序列上选择结构。

PopCount已变得如此普遍,即GCC和Clang将检测到PopCount的实现并将其替换为内置指令。想象一下clippy去“我看到你正在努力实施popcount,让我继续为你解决这个问题”!相关的LLVM代码在这里。 Daniel Lemire指出这一点是现代编纂者令人惊讶的聪明才智。

从开头笼罩在谜团中,Popcount已经出现为一般有用的,如果略有异常,CPU指令。我喜欢它如何将这种不同的计算领域联系在一起,我想知道那里有多少奇怪的指令。如果你有一个喜欢的话,我很乐意听到它!