【Hacker News搬运】AVX位三元逻辑指令损坏
-
Title: AVX Bitwise ternary logic instruction busted
AVX位三元逻辑指令损坏
Text:
Url: https://arnaud-carre.github.io/2024-10-06-vpternlogd/
标题:AVX-512 位运算三值逻辑指令解析 摘要: 本文深入探讨了 AVX-512 位运算三值逻辑指令(vpternlogd)的设计和功能。通过对比 1985 年的 Amiga blitter 芯片,作者揭示了这一指令背后的历史渊源和设计理念。 正文: 在观察 Tom Forsyth 关于 AVX-512 指令集架构(ISA)设计的演讲时,作者注意到了一个名为 vpternlogd 的指令。这是一个位运算三值逻辑操作指令,能够使用三个输入源执行任何位运算布尔逻辑。例如,可以创建如下的复杂逻辑运算: 作者解释说,为满足每个可能的用户需求添加特定的指令会非常繁琐,这将需要大量新的助记符、文档和测试。相反,他们选择了更智能(也许更懒惰?)的方法:一个单一且灵活的指令。该指令接收三个寄存器作为输入,以及一个定义具体位运算的 8 位立即值。不幸的是,大多数文档只是说“立即值确定特定的二进制函数”,这并不十分有用。 作者发现这个 8 位立即值让他想起了 1985 年的老朋友:Amiga blitter 芯片。在 1980 年代,计算机通常有专门用于处理图形的定制芯片。然而,这些芯片并不处理像三角形光栅化或可编程着色器这样的复杂任务。当时,“图形”主要是指处理位图。例如,Commodore Amiga 500 就有一个 blitter 芯片,其主要功能是在一个位置到另一个位置移动位图图形的同时应用逻辑运算。Amiga 的 blitter 可以一次处理多达三个位图源,并对它们执行逻辑运算。要指定要使用的操作,需要设置芯片中的 8 位值,称为“minterm”。 有趣的是,即使是许多熟练的 Amiga 程序员也不知道如何计算 minterm 值。大多数人只是从其他演示中重复使用常见的值。例如,为了清除缓冲区,他们会使用 0x00。为了配置 blitter 绘制带遮罩的精灵,他们会使用 0xE2。但对于任何其他奇怪的定制功能,大多数人都会迷失在时光中。 Amiga blitter 用户手册也没有太大帮助。1989 年的“Amiga 硬件参考手册”试图使用令人困惑的符号解释 minterm 计算,这让当时的许多年轻演示制作人员感到沮丧。 作者介绍了一种计算 minterm 值的简单方法。即使你并不打算很快编程 Amiga blitter,你也可能会发现这种方法对处理现代 AVX 三值逻辑指令很有用——它们的工作方式完全相同! 最后,作者提到一个有趣的巧合:Amiga 中非常常见的 minterm 值 0xE2,常用于渲染带遮罩的 2D 精灵。通过简单的编程术语思考计算带遮罩精灵的 minterm 是很容易的:当遮罩像素(B)被设置时,结果是精灵(A)。如果遮罩像素未设置,结果是背景(C)。从下到上读取 8 位:11100010,或 0xE2。 结论: 这篇论文通过比较 AVX-512 中的 vpternlogd 指令和 1985 年的 Amiga blitter 芯片,展示了计算机指令集设计的历史连续性和创新。它还揭示了在 Intel 官方文档中可能存在的 Amiga 影响的痕迹。
Post by: msephton
Comments:
mmozeiko: There is a simple way to get that immediate from expression you want to calculate. For example, if you want to calculate following expression:<p><pre><code> (NOT A) OR ((NOT B) XOR (C AND A))
</code></pre>
then you simply write<p><pre><code> ~_MM_TERNLOG_A | (~_MM_TERNLOG_B ^ (_MM_TERNLOG_C & _MM_TERNLOG_A))
</code></pre>
Literally the expression you want to calculate. It evaluates to immediate from _MM_TERNLOG_A/B/C constants defined in intrinsic headers, at least for gcc & clang:<p><pre><code> typedef enum {
_MM_TERNLOG_A = 0xF0,
_MM_TERNLOG_B = 0xCC,
_MM_TERNLOG_C = 0xAA
} _MM_TERNLOG_ENUM;
</code></pre>
For MSVC you define them yourself.mmozeiko: 有一种简单的方法可以从要计算的表达式中立即得到它。例如,如果你想计算以下表达式:<p><pre><code>(NOT A)或((NOT B)XOR(C AND A))</code></pre>然后,您只需编写<p><pre><code>~MM_TERNLOG_A|(~MM TERNLOG_B^(MM TER NLOG_C和_MM TRENLOG_A))</code></pre>字面意思是你想要计算的表达式。它从_MM_TERNLOG_A评估为立即;B/;在内部头文件中定义的C常量,至少对于gcc&;clang:<p><pre><code>typedef枚举{_MM_TERNLOG_A=0xF0,_MM_TERNLOG_B=0xCC,_MM_TERNLOG_C=0xAA}_MM_TERNLOG_ENUM;</code></pre>对于MSVC,你自己定义它们。
Sniffnoy: Oh, I thought the title was saying that the instruction doesn't work properly! (The article actually just explains how it works.)
Sniffnoy: 哦,我以为标题是说指令没有;不能正常工作!(这篇文章实际上只是解释了它是如何工作的。)
Lerc: My teenage self did not write "CRAP!" on that page of the hardware manual, but I stared at it for so long trying to figure it out.<p>In the end I did what pretty much everyone else did, Found the BLTCON0 for Bobs and straight copies and then pretended I newer saw the thing.<p>I did however get an A+ in computational logic at university years later, so maybe some of the trauma turned out to be beneficial.
Lerc: 我十几岁的时候没有写过";废话&“;在硬件手册的那一页上,但我盯着它看了很久,试图弄清楚<p> 最后,我做了几乎所有人都做的事情,找到了鲍勃的BLTCON0和直接复制品,然后假装我新看到了这件事<p> 然而,几年后,我在大学的计算逻辑课程中获得了A+,所以也许一些创伤是有益的。
cubefox: About the title: "Ternary logic" usually means "logic with three truth values". But this piece covers a compiler instruction which handles all binary logic gates with three inputs.
cubefox: 关于标题:";三元逻辑";通常意味着“;具有三个真值的逻辑”;。但本文涵盖了一条编译器指令,该指令处理所有具有三个输入的二进制逻辑门。
kens: I'll point out that this is the same way that FPGAs implement arbitrary logic functions, as lookup tables (LUTs).
kens: 我;ll指出,这与FPGA实现任意逻辑功能的方式相同,如查找表(LUT)。