今天的问题相当短。考虑以下玩具 C 程序 shuffle.c
,用于反转寄存器 xmm0
中的两个压缩 double :
#include <stdio.h>
void main () {
double x[2] = {0.0, 1.0};
asm volatile (
"movupd (%[x]), %%xmm0\n\t"
"shufpd $1, %%xmm0, %%xmm0\n\t" /* method 1 */
//"pshufd $78, %%xmm0, %%xmm0\n\t" /* method 2 */
"movupd %%xmm0, (%[x])\n\t"
:
: [x] "r" (x)
: "xmm0", "memory");
printf("x[0] = %.2f, x[1] = %.2f\n", x[0], x[1]);
}
空运行后:gcc -msse3 -o shuffle shuffle.c | ./test
,两个方法/指令都会返回正确的结果x[0] = 1.00,x[1] = 0.00
。 This page表示 shufpd
的延迟为 6 个周期,而 intel intrinsic guide表示 pshufd
只有 1 个周期的延迟。这听起来像是对 pshufd 的极大偏好。然而,该指令确实适用于压缩整数。当将其用于打包 double 时,是否会因“错误类型”而受到任何惩罚?
作为一个类似的问题,我还听说指令movaps
比movapd
小1个字节,并且它们通过从16位读取128位来完成相同的事情对齐的地址。那么我们是否可以始终使用前者来移动(在 XMM 之间)/加载(从内存)/存储(到内存)?这看起来很疯狂。我认为必须有一些理由来拒绝这一点。有人可以给我一个解释吗?谢谢。
最佳答案
您总是会得到正确的结果,但这对性能很重要。
首选对 FP 数据进行 FP 洗牌,这些数据将作为 FP 数学指令的输入(如 addps
或 vfma...
,而不是像 xorps
这样的 insn)。
这可以避免某些微架构(包括当前可能的英特尔芯片)上出现任何额外的旁路延迟延迟。请参阅Agner Fog's microarchitecture guide 。 AMD Bulldozer 系列在 vector 整数域中执行所有洗牌,因此无论您使用哪种洗牌,都会存在旁路延迟。
如果它可以节省指令,那么无论如何使用整数洗牌都是值得的。 (但通常情况恰恰相反,您想要使用 shufps
来组合来自两个整数 vector 的数据。在更多情况下这也没有问题,而且大多数情况下仅在 Nehalem、IIRC 上出现问题。)
http://x86.renejeschke.de/html/file_module_x86_id_293.html列出了 CPUID 0F3n/0F2n CPU 的延迟,即 Pentium4(系列 0xF 型号 2 (Northwood)/型号 3 (Prescott))。这些数字显然完全不相关,甚至与 Agner Fog 的 P4 表 shufpd
不匹配。 .
英特尔的内在函数指南有时也包含与实验测试不匹配的数字。请参阅Agner Fog's instruction tables以获得良好的延迟/吞吐量数据,以及了解详细信息的微架构指南。
<强> movaps
与 movapd
:现有的微架构不关心您使用的内容。 future 有人有可能设计出保留 double
的 x86 CPU。与 float
分开的 vector 内部 vector ,但目前唯一的区别是 int 与 FP。
总是更喜欢ps
当行为相同时的指令( xorps
超过 xorpd
, movhps
超过 movhpd
)。
一些编译器(也许是 gcc 和 clang,我忘了)会编译 _mm_store_si128
整数 vector 存储到 movaps
,因为在任何现有硬件上都没有性能下降,而且它短了一个字节。
IIRC,使用 movaps
加载整数 vector 数据也没有性能缺点。/movups
,但我对此不太确定。
不过,使用错误的 mov 指令进行 reg-reg 移动有一个性能缺点。 movdqa xmm1, xmm2
两个 FP 指令之间的关系对 Nehalem 来说很糟糕。
回复:您的内联汇编:
不需要是 volatile
,您可以删除 "memory"
如果您使用 16 字节结构或类似 "+m"
的东西,则会造成破坏输入/输出操作数。或者 __m128d
的“+x” vector 寄存器操作数多变的。
除非您在内联汇编或独立函数中编写整个循环,否则从内在函数中获得的结果可能比从内联汇编中获得更好的结果。
请参阅x86标记 wiki 以获取我的内联 asm 指南的链接。
关于c - 在 XMM 中反转两个压缩 double 时,对 SHUFPD 或 PSHUFD 有何偏好?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37180565/