x64 SSE数据类型

时间:2013-03-10 13:33:02

标签: assembly 64-bit sse

AMD64架构程序员手册第1卷:应用程序编程第226页说明SSE指令:

  

处理器在执行指令之前不检查指令操作数的数据类型。它   只在执行点检查它们。例如,如果处理器执行算术运算   采用双精度操作数但由单精度操作数提供的指令   MOVx指令,处理器首先将操作数从单精度转换为双精度   在执行算术运算之前的精度,结果是正确的。然而   所需的转换可能会导致性能下降。

我不明白这一点;我原以为ymm寄存器只包含256位,每个指令根据其预期的操作数进行解释,由您来确保存在正确的类型,并且在所描述的场景中,CPU将全速运行并默默地给出错误的答案。

我错过了什么?

1 个答案:

答案 0 :(得分:1)

Intel® 64 and IA-32 Architectures Optimization Reference Manual§5.1说了一些关于混合整数/ FP“数据类型”的东西(但好奇的不是单打和双打):

  

编写适用于整数和浮点数据的SIMD代码时,请使用   SIMD的子集转换指令或加载/存储指令以确保这一点   XMM寄存器中的输入操作数包含正确定义的数据类型   匹配指令。

     

包含交叉类型用法的代码序列会产生相同的结果   不同的实现,但会导致显着的性能损失。运用   SSE / SSE2 / SSE3 / SSSE3 / SSE44.1指令操作类型不匹配   强烈建议不要使用XMM寄存器中的SIMD数据。

Intel® 64 and IA-32 Architectures Software Developer’s Manual似乎令人困惑:

  

SSE和SSE2扩展定义了打包和标量浮点数据类型以及128位上的类型化操作   SIMD整数数据类型,但IA-32处理器不在体系结构级别强制执行此类型。他们只   在微体系结构层面强制执行。

     

...

     

Pentium 4和Intel Xeon处理器执行这些指令而不会产生无效操作数异常   (#UD)并将在寄存器XMM0中产生预期的结果(即,每个寄存器的高位和低位64位将   被视为双精度浮点值,处理器将相应地对它们进行操作。)

     

...

     

在此示例中:可以使用XORPS或PXOR代替XORPD并产生相同的正确结果。然而,   由于操作数数据类型和指令数据类型之间的类型不匹配,延迟惩罚将会   由于在微体系结构级别执行指令而引起的。

     

使用错误类型的移动指令也可能导致延迟处罚。例如,MOVAPS和   MOVAPD都可以用于将打包的单精度操作数从内存移动到XMM寄存器。然而,   如果使用MOVAPD,当正确类型的指令尝试使用数据时,将导致延迟惩罚   登记册。

     

请注意,将数据从XMM寄存器移动到内存时不会产生这些延迟惩罚。

真的不知道它是什么意思“他们只在微体系结构层面强制执行它”,除了它表明不同的“数据类型”被μarch处理不同。我有一些猜测:

  • AIUI,x86核心通常使用register renaming,因为寄存器不足。也许他们在内部对整数/单/双操作数使用不同的寄存器,因此它们可以更靠近相应的向量单元。
  • 似乎有可能使用不同的格式在内部表示FP编号(例如,使用更大的指数来消除denorms)并仅在必要时转换为规范位。
  • CPU使用“forwarding”或“绕过”,以便执行单元在后续指令可以使用之前不必等待数据写入寄存器,通常可以节省一个或两个周期。这可能不会发生在整数和FP单位之间。