assembly – 切换执行单元域时的旁路延迟

我试图在切换执行单元的域时理解可能的旁路延迟.

例如,以下两行代码给出了完全相同的结果.

_mm_add_ps(x, _mm_castsi128_ps(_mm_slli_si128(_mm_castps_si128(x), 8)));
_mm_add_ps(x, _mm_shuffle_ps(_mm_setzero_ps(), x, 0x40));

哪一行代码更好用?

第一行的汇编输出给出:

vpslldq xmm1, xmm0, 8
vaddps  xmm0, xmm1, xmm0

第二行的汇编输出给出:

vshufps xmm1, xmm0, XMMWORD PTR [rcx], 64   ; 00000040H
vaddps  xmm2, xmm1, XMMWORD PTR [rcx]

现在,如果我看一下Agner Fog的微体系结构manual,他在第112页给出了一个例子,在浮点值上使用整数shuffle(pshufd),而在float值上使用float shuffle(shufps).交换域增加了4个额外的时钟周期,因此使用shufps的解决方案更好.

我使用_mm_slli_si128列出的第一行代码必须在整数和浮点向量之间切换域.使用_mm_shuffle_ps的第二个停留在同一个域中.这是否意味着第二行代码是更好的解决方案?

英特尔 optimization guide的2.1.4节表明你(和Agner)在这件事上是对的 –

When a source of a micro-op executed in one stack comes from a micro-op executed in another stack, a one- or two-cycle delay can occur. The delay occurs also for tran-sitions between Intel SSE integer and Intel SSE floating-point operation.

所以一般来说,你最好尽可能地保持在同一个堆栈/域中.

当然,基准测试始终是首选,只有在这确实是代码瓶颈的情况下才值得处理.

相关文章
相关标签/搜索