跳到主内容
@wquguru
精选88Hacker News Best(web_list)行业动态

Intel SDM中幽灵指令vfmaddrnd231pd的起源与废弃复盘

Who is vfmaddrnd231pd?

原文
发到 X
推荐理由

对底层指令集历史与技术债务的深度挖掘,适合关注CPU架构与编译器工程的读者阅读。

Who is vfmaddrnd231pd??

vfmaddrnd231pd 是谁??

October 12, 2026 Hacker News Lobsters

2026年10月12日 Hacker News Lobsters

vfmaddrnd231pd is a unique instruction from the FMA instruction set. Most instructions in that set have mnemonics like vfmadd231pd, but here rnd means something very specific. The Intel Software Development Manual documents it as:

vfmaddrnd231pd 是 FMA 指令集的一条独特指令。该集合中的大多数指令助记符类似于 vfmadd231pd,但这里的 rnd 具有非常特定的含义。《Intel 软件开发手册》(SDM)将其记录为:

VFMADDRND231PD – Fused Multiply-Add of Packed Double-Precision Floating-Point Values with rounding control

VFMADDRND231PD – 带舍入控制的打包双精度浮点值的融合乘加运算

[…] The immediate byte defines several bit fields that control rounding, DAZ, FTZ, and exception suppression (See Table 5-3).

[…] 立即数字节定义了几个位字段,用于控制舍入、DAZ、FTZ 和异常抑制(参见表 5-3)。

Most x86 floating-point instructions use the global rounding mode and settings, changing which is pretty slow. But vfmaddrnd231pd allows the rounding mode to be controlled on a per-instruction basis, and since FMA can emulate addition, subtraction, and multiplication, this mechanism effectively allows any arithmetic to have controllable rounding without AVX-512 – making some algorithms that rely on rounding incredibly faster.

大多数 x86 浮点指令使用全局舍入模式和设置,更改这些设置相当缓慢。但 vfmaddrnd231pd 允许按每条指令控制舍入模式,并且由于 FMA 可以模拟加法、减法和乘法,这种机制有效地允许任何算术运算都具有可控的舍入,而无需 AVX-512——这使得一些依赖舍入的算法变得极其快速。

Or so it would, if this instruction actually existed. GNU assembler doesn’t recognize it. The Intel C/C++ Compiler intrinsics _mm_fmaddround_pd and _mm256_fmaddround_pd that SDM mentions are absent not only from Clang, but from ICC as well. Trying to assemble the instructions by hand from the SDM opcode list reveals another issue:

如果这条指令真的存在,情况本该如此。GNU 汇编器无法识别它。SDM 中提到的 Intel C/C++ 编译器内在函数 _mm_fmaddround_pd 和 _mm256_fmaddround_pd 不仅不在 Clang 中,也不在 ICC 中。尝试从 SDM 操作码列表中手动汇编这些指令揭示了另一个问题:

VEX.DDS.128.66.0F3A.W1 B8 /r /ib

VEX is the VEX prefix, but what is DDS? This opcode is the only mention of DDS in the SDM, and this SO answer says that DDS is merely used for documentation and was removed from later SDM versions, but the fact that it’s still present here is suspicious. And when you actually run the instruction on a CPU that supports the FMA instruction set, like my Haswell, it raises #UD (“UnDefined instruction”)!

VEX 是 VEX 前缀,但 DDS 是什么?这是 SDM 中唯一提到 DDS 的地方,这个 Stack Overflow 回答指出 DDS 仅用于文档目的,并在后来的 SDM 版本中被移除,但它仍然出现在这里的事实令人怀疑。而且,当你在一台支持 FMA 指令集的 CPU(比如我的 Haswell)上实际运行该指令时,它会引发 #UD(“未定义指令”)!

I already found it strange that the SDM only lists vfmaddrnd231pd and not other variants like using pd/ps/sd/ss or 132/213/231, which other FMA instructions have, but this confirmed my suspicions. It was at that point that I downloaded a more recent version of the SDM and noticed that this instruction is absent in the 2026 edition of the SDM, despite being present in the 2024 version.

我已经觉得奇怪的是,SDM 只列出了 vfmaddrnd231pd,而没有列出其他变体,如使用 pd/ps/sd/ss 或 132/213/231 的情况,而其他 FMA 指令都有这些变体,但这证实了我的怀疑。就在那时,我下载了更新版本的 SDM,并注意到尽管该指令出现在 2024 版 SDM 中,但在 2026 版 SDM 中却消失了。

I must say I’m incredibly confused. This instruction doesn’t look like a typo in the documentation, since the docs contain unique tables and pseudocode that isn’t similar to any other instruction. My best hypothesis is that Intel wanted to add the vfmaddrnd* set, then found an issue with it at the last moment and removed it from the CPU, but didn’t quite adjust the SDM correctly. But I have no way to confirm that.

我必须说,我感到非常困惑。这条指令看起来不像文档中的笔误,因为文档包含独特的表格和伪代码,与其他任何指令都不相似。我最好的假设是,英特尔原本想添加 vfmaddrnd* 集合,但在最后一刻发现了问题并将其从 CPU 中移除,但没有完全正确地调整 SDM(软件开发者手册)。但我无法证实这一点。

If anyone reading this has a friend at Intel, I’d love to know the answer.

如果有任何读到这篇文章的人认识在英特尔工作的朋友,我很想知道答案。

Update

更新

seastarer and 039234562456 gave me enough pointers to crack this.

seastarer 和 039234562456 给了我足够的提示,让我破解了这个问题。

Back in 2023, Intel failed to add AVX-512 support to consumer CPUs due to hardware limitations, but still wanted to add some goodies from AVX-512. That’s how AVX10 was born – a new extension that looked roughly like AVX-512, but had conditional support for 512-bit vector lengths.

早在 2023 年,由于硬件限制,英特尔未能向消费级 CPU 添加 AVX-512 支持,但仍希望加入一些 AVX-512 的特性。这就是 AVX10 的诞生——一种新的扩展,大致类似于 AVX-512,但条件性地支持 512 位向量长度。

AVX-512 uses a strange instruction encoding with the EVEX prefix. For compactness, the bits responsible for the static rounding mode are reused for the operation width (128, 256, or 512 bits), so only scalar and 512-bit operations can customize rounding.

AVX-512 使用带有 EVEX 前缀的奇怪指令编码。为了紧凑起见,负责静态舍入模式的位被重用为操作宽度(128、256 或 512 位),因此只有标量和 512 位操作可以自定义舍入。

This was a problem for AVX10, which didn’t support 512-bit operations: if it interpreted the same instruction as operating on 256-bit values instead of 512-bit ones, different CPUs would behave inconsistently. So AVX10 had to use a different encoding for its own custom rounding modes.

这对不支持 512 位操作的 AVX10 来说是个问题:如果它解释相同的指令为对 256 位值而非 512 位值进行操作,不同的 CPU 将表现出不一致的行为。因此,AVX10 必须为其自定义舍入模式使用不同的编码。

My theory is that originally, Intel decided that the easiest way to do this was to add an immediate byte that controls the rounding, which is how vfmaddrnd231pd and similar instructions for other arithmetic operations were born. Notice that it uses a VEX prefix, not the AVX-512-specific EVEX prefix – this would allow CPUs without 512-bit vectors to avoid handling the EVEX prefix at all. Since they added an entire byte, they utilized it in full: 2 bits for the rounding mode, 6 bits for everything else they thought might be useful.

我的理论是,最初英特尔决定最简单的方法是添加一个控制舍入的立即数字节,从而诞生了 vfmaddrnd231pd 和其他算术运算的类似指令。请注意,它使用的是 VEX 前缀,而不是 AVX-512 特有的 EVEX 前缀——这将使没有 512 位向量的 CPU 完全避免处理 EVEX 前缀。由于他们添加了一个完整的字节,他们充分利用了它:2 位用于舍入模式,其余 6 位用于他们认为可能有用的一切。

It seems like by 2024, Intel decided that this approach won’t work. And I get it: it’s odd that vfmaddrnd231pd was more powerful than AVX-512 instructions, but only supported 256-bit vectors. And if it supported 512-bit vectors, the rounding mode control built into AVX-512 would become obsolete for the most part.

似乎到了 2024 年,英特尔认为这种方法行不通。我也理解:vfmaddrnd231pd 比 AVX-512 指令更强大,却只支持 256 位向量,这很奇怪。而且如果它支持 512 位向量,内置于 AVX-512 的舍入模式控制在很大程度上就会过时。

So Intel bit the bullet, dedicated the last unused bit in the EVEX prefix to enabling rounding modes for 256-bit vectors, and reused the AVX-512 instruction encoding for AVX10. This also allowed them to reuse the AVX-512 assembly syntax and avoid introducing new mnemonics, at which point the vfmaddrnd231pd mnemonic and others became unnecessary. During this process, someone forgot to remove vfmaddrnd231pd specifically from the SDM draft.

于是英特尔破釜沉舟,将 EVEX 前缀中最后一个未使用的比特位专门用于启用 256 位向量的舍入模式,并复用了 AVX-512 的指令编码来实现 AVX10。这也使他们能够复用 AVX-512 的汇编语法,避免引入新的助记符,此时 vfmaddrnd231pd 等助记符便不再必要。在此过程中,有人忘记从 SDM(软件开发者手册)草稿中移除 vfmaddrnd231pd。

By 2025, AVX-512 was considered table stakes due to the popularity of Zen 4, and Intel finally decided to make 512-bit support unconditional in AVX10. This made this entire hack unnecessary, so Intel updated the AVX10 whitepaper:

到了 2025 年,由于 Zen 4 的普及,AVX-512 已被视为标配,英特尔最终决定在 AVX10 中无条件支持 512 位。这使得整个变通方案变得多余,因此英特尔更新了 AVX10 白皮书:

Removed references to 256-bit maximum vector register size, enumeration of vector-length support, and 256-bit instructions supporting embedded rounding.

删除了对最大向量寄存器大小为 256 位的引用、向量长度支持的枚举以及支持嵌入式舍入的 256 位指令。

…and submitted patches to GCC removing 256-bit rounding support:

……并向 GCC 提交了移除 256 位舍入支持的补丁:

In this new whitepaper, all the platforms will support 512 bit vector width (previously, E-core is up to 256 bit, leading to hybrid clients and Atom Server 256 bit only). Also, 256 bit rounding is not that useful because we currently have rounding feature directly on E-core now and no need to use 256-bit rounding as somehow a workaround. HW will remove that support.

在这份新版白皮书中,所有平台都将支持 512 位向量宽度(此前,E-core 最高仅支持 256 位,导致混合架构客户端和 Atom Server 仅限 256 位)。此外,256 位舍入并非那么有用,因为目前我们直接在 E-core 上拥有舍入功能,无需再使用 256 位舍入作为一种变通手段。硬件将移除对该功能的支持。

We can partially confirm this theory by inspecting the patches. One of them is named:

我们可以通过检查补丁来部分证实这一理论。其中一个是名为:

Revert “AVX10.2 ymm rounding: Support vfmadd{132, 231, 213}p{s, d, h} intrins”

…and removes multiple intrinsics, including _mm256_fmadd_round_pd, which is named very similarly to the documented intrinsic for the ghost instruction, _mm256_fmaddround_pd.

……并移除了多个内在函数(intrinsics),包括 _mm256_fmadd_round_pd,其命名与幽灵指令文档化的内在函数 _mm256_fmaddround_pd 非常相似。

At a later point, someone at Intel realized that vfmaddrnd231pd was still mentioned in the SDM and removed it.

在稍后的某个时间点,英特尔的某位人员意识到 SDM 中仍然提到了 vfmaddrnd231pd,并将其移除。

Summing up: I believe that vfmaddrnd231pd is of AVX10 lineage. I think it was added during the prototyping stage of AVX10, then reworked to use a different instruction encoding, until it finally became unnecessary. Market pressures, timing constraints, and weird tech debt affected the design process enough that things had to be reworked on the fly, and at some point someone slipped up and accidentally documented an instruction that has never existed in released hardware.

总结:我认为 vfmaddrnd231pd 源自 AVX10 系列。我认为它是在 AVX10 的原型设计阶段添加的,随后经过重新设计以使用不同的指令编码,直到最终变得不再必要。市场压力、时间限制以及奇怪的技术债务影响了设计过程,导致事物不得不随时重新调整,而在某个时刻,有人疏忽了,意外地记录了一条从未在发布硬件中存在过的指令。

更进一步:量化金融体系

看懂新闻只是起点——沿量化金融路径,把它变成能交付的工程能力

进入量化体系 →

相似阅读

关联信息,但可能不是同一事件