64 位机器上 QWORD 的大小是多少?
What's the size of a QWORD on a 64-bit machine?
我目前正在寻找上述问题的答案。到目前为止,我发现人们说,字长指的是处理器寄存器的大小,这表明在 64 位机器上字长为 64 位,因此 QWORD(4 * 字)的大小为 256 位。
但另一方面,我发现像 this 这样的消息来源说大小为 128 位(32 位为 64 位,64 位为 64 位),而其他人则认为大小会为 64 位。但最后一个在某种程度上与微软有关,它通过将单词的大小定义为 16 位来混淆所有人,从而使事情变得更糟。
也许有人可以解决我的困惑并启发我这个话题。
在 x86 terminology/documentation 中,一个“字”是 16 位,因为 x86 是从 16 位 8086 演化而来的。随着扩展的加入改变了术语的含义只会让人感到困惑,因为英特尔仍然必须记录 16 位模式和所有内容,并且像 cwd
(符号扩展字到双字)这样的指令助记符将术语烘焙到 ISA 中。
- x86 字 = 2 个字节
- x86 dword = 4 字节(双字)
- x86 qword = 8 字节(四字)
- x86 double-quad 或 xmmword = 16 字节,例如
movdqa xmm0, [rdi]
.
同样在cqo
mnemonic,oct-word。 (将 RAX 符号扩展到 RDX:RAX,例如 idiv
之前)
然后我们有有趣的指令,例如 punpcklqdq
: shuffle together two qwords into a dqword, or pclmulqdq
for carry-less multiplication of qwords, producing a dq full result. But beyond that, SIMD mnemonics tend to be AVX vextracti128
or AVX512 (with optional per-element masking) vextractf64x4
来提取 ZMM 寄存器的高 256 位。
更不用说像“tbyte”= 10 字节 x87 扩展精度浮点数这样的东西了; x86 很奇怪,并不是所有东西都是 2 的幂。还有 48 位 seg:off 16:32 保护模式下的远指针。 (基本没用过,就32位偏移部分)
大多数其他 64 位 ISA 从 32 位 ISA 演变而来(AArch64、MIPS64、PowerPC64 等),或者从一开始就是 64 位的 (Alpha) , 所以“字”在该上下文中表示 32 位。
- 32 位字 = 4 字节
- dword = 8 字节(双字),例如MIPS
daddu
是 64 位整数 add
- qword = 16 字节(四字),如果完全支持的话。
“机器字”并在体系结构上贴上标签。
“机器字”的完整概念,它的机器代码格式是字节流,对多个操作数大小的同等支持,以及大多数情况下不对齐的 loads/stores不关心自然对齐的东西,只关心普通可缓存内存的缓存行边界。
即使是“面向字的”RISC 的寄存器和高速缓存访问的自然大小也可能与其指令宽度或它们的文档用作“字”的宽度不同。
“字长”的整个概念通常都被高估了,不仅仅是在 x86 上。即使是 64 位 RISC ISA 也可以 load/store 以相同的效率对齐 32 位或 64 位内存,因此请选择对您正在做的事情最有用的那个。不要根据确定哪一个是机器的“字大小”来做出选择,除非只有一个最有效的大小(例如,某些 32 位 RISC 上的 32 位),那么您可以有效地将其称为字大小。
在我听说过的任何 64 位机器上,“单词”并不代表 64 位。即使是 DEC Alpha AXP,从头开始设计为积极的 64 位,也使用 32 位指令字。 IIRC,说明书称一个字32位。
能够使用一条指令将 64 位加载到整数寄存器中并不会使其成为“字长”。 位数和字长没有硬性的具体技术含义;大多数 CPU 内部都有多种不同的尺寸。 (例如,自 Haswell 以来,英特尔 L2 和 L1d 缓存之间有 64 byte 总线,以及 32 字节 SIMD load/store。)
因此,基本上由 CPU 供应商的文档作者来选择他们的 ISA 的“字”(以及双字/四字)的含义。
有趣的事实:SPARC64 谈论“短字”(32 位)与“长字”(64 位),而不是字/双字。我不知道在 64 位 SPARC 文档中是否只有没有任何限定符的“单词”有任何意义。
我目前正在寻找上述问题的答案。到目前为止,我发现人们说,字长指的是处理器寄存器的大小,这表明在 64 位机器上字长为 64 位,因此 QWORD(4 * 字)的大小为 256 位。
但另一方面,我发现像 this 这样的消息来源说大小为 128 位(32 位为 64 位,64 位为 64 位),而其他人则认为大小会为 64 位。但最后一个在某种程度上与微软有关,它通过将单词的大小定义为 16 位来混淆所有人,从而使事情变得更糟。
也许有人可以解决我的困惑并启发我这个话题。
在 x86 terminology/documentation 中,一个“字”是 16 位,因为 x86 是从 16 位 8086 演化而来的。随着扩展的加入改变了术语的含义只会让人感到困惑,因为英特尔仍然必须记录 16 位模式和所有内容,并且像 cwd
(符号扩展字到双字)这样的指令助记符将术语烘焙到 ISA 中。
- x86 字 = 2 个字节
- x86 dword = 4 字节(双字)
- x86 qword = 8 字节(四字)
- x86 double-quad 或 xmmword = 16 字节,例如
movdqa xmm0, [rdi]
.
同样在cqo
mnemonic,oct-word。 (将 RAX 符号扩展到 RDX:RAX,例如idiv
之前)
然后我们有有趣的指令,例如 punpcklqdq
: shuffle together two qwords into a dqword, or pclmulqdq
for carry-less multiplication of qwords, producing a dq full result. But beyond that, SIMD mnemonics tend to be AVX vextracti128
or AVX512 (with optional per-element masking) vextractf64x4
来提取 ZMM 寄存器的高 256 位。
更不用说像“tbyte”= 10 字节 x87 扩展精度浮点数这样的东西了; x86 很奇怪,并不是所有东西都是 2 的幂。还有 48 位 seg:off 16:32 保护模式下的远指针。 (基本没用过,就32位偏移部分)
大多数其他 64 位 ISA 从 32 位 ISA 演变而来(AArch64、MIPS64、PowerPC64 等),或者从一开始就是 64 位的 (Alpha) , 所以“字”在该上下文中表示 32 位。
- 32 位字 = 4 字节
- dword = 8 字节(双字),例如MIPS
daddu
是 64 位整数 add - qword = 16 字节(四字),如果完全支持的话。
“机器字”并在体系结构上贴上标签。
“机器字”的完整概念
即使是“面向字的”RISC 的寄存器和高速缓存访问的自然大小也可能与其指令宽度或它们的文档用作“字”的宽度不同。
“字长”的整个概念通常都被高估了,不仅仅是在 x86 上。即使是 64 位 RISC ISA 也可以 load/store 以相同的效率对齐 32 位或 64 位内存,因此请选择对您正在做的事情最有用的那个。不要根据确定哪一个是机器的“字大小”来做出选择,除非只有一个最有效的大小(例如,某些 32 位 RISC 上的 32 位),那么您可以有效地将其称为字大小。
在我听说过的任何 64 位机器上,“单词”并不代表 64 位。即使是 DEC Alpha AXP,从头开始设计为积极的 64 位,也使用 32 位指令字。 IIRC,说明书称一个字32位。
能够使用一条指令将 64 位加载到整数寄存器中并不会使其成为“字长”。 位数和字长没有硬性的具体技术含义;大多数 CPU 内部都有多种不同的尺寸。 (例如,自 Haswell 以来,英特尔 L2 和 L1d 缓存之间有 64 byte 总线,以及 32 字节 SIMD load/store。)
因此,基本上由 CPU 供应商的文档作者来选择他们的 ISA 的“字”(以及双字/四字)的含义。
有趣的事实:SPARC64 谈论“短字”(32 位)与“长字”(64 位),而不是字/双字。我不知道在 64 位 SPARC 文档中是否只有没有任何限定符的“单词”有任何意义。