为什么和哪里使用对齐16用于指令的SSE对齐?

时间:2016-09-21 10:29:47

标签: assembly 64-bit sse

我正在阅读Apress的Modern x86汇编语言书。对于编程64位SSE示例,作者将对齐16 放入代码中的特定点。 E.g

    .code
ImageUint8ToFloat_ proc frame
_CreateFrame U2F_,0,64               ; helper macros to create prolog
_SaveXmmRegs xmm10,xmm11,xmm12,xmm13 ; helper macros to create prolog

_EndProlog  ; helper macros to create prolog

...

shrd r8d,
pxor xmm5,xmm5

align 16  ; Why this is here ?
@@:
movdqa xmm0,xmmword ptr [rdx]
movdqa xmm10,xmmword ptr [rdx+16]

movdqa xmm2,xmm0
punpcklbw xmm0,xmm5
punpckhbw xmm2,xmm5
movdqa xmm1,xmm0
movdqa xmm3,xmm2

...

作者解释说,有必要将对齐16 ,因为我们使用的是SSE,因此指令本身是对齐的。没关系。我的问题是为什么作者选择将对齐16 放到该特定位置。作为程序员,我应该如何确定对齐16 的正确位置?为什么不早点或晚点?

1 个答案:

答案 0 :(得分:4)

没有必要。它偶尔会有益。

现代处理器以16个块(或者32个,有点像AMD,奇怪的东西)字节来获取代码。当然是对齐的。如果你跳到这个块的末尾附近,你就浪费了大部分的提取,并且在那个周期中你只解码了1个或多个0指令。这是一个巨大的浪费,所以最好跳到一个街区的开头。

这并不总是重要的,例如,如果代码在循环缓冲区或μop缓存中(如果存在)。通常几乎任何循环都适合μops缓存,在比SandyBridge更早的处理器上,很容易做出一个不适合循环缓冲区的循环,这使得获取吞吐量很重要。即使循环可以适合循环缓冲区,对齐仍然有助于Core2,因为未对齐有效地使循环缓冲区变小(它基于16字节的代码块,在预解码后缓存)。有一些更奇怪的细节,但它都是关于古代的μarchs所以我会跳过它。关键是,在像Nehalem和更老的时候,你应该经常对齐循环。

虽然片段不是很清楚,但看起来它们已经对齐了一个标签,它将循环回来。所以它正在调整循环。它对现代的μarchs并不重要。