【发布时间】:2015-02-22 17:12:29
【问题描述】:
我正在使用一些 SSE 汇编代码,其中我没有足够的 xmm 寄存器来同时将所有临时结果和有用的常量保存在寄存器中。
作为一种解决方法,对于一些具有相同分量的常量向量,我将几个向量“压缩”到一个xmm 寄存器中,下面是xmm14。我使用pshufd 指令来解压我需要的常量向量。这条指令有一点延迟,但由于它需要一个源寄存器和一个目标寄存器,否则非常方便:
…
Lfour_15_9:
.long 4
.long 1549556828
.long 909522486
.long 0
…
movdqa Lfour_15_9(%rip), %xmm14
…
pshufd $0, %xmm14, %xmm4
paddd %xmm4, %xmm3
…
pshufd $0b10101010, %xmm14, %xmm5
…
pshufd $0b10101010, %xmm14, %xmm5
…
pshufd $0b01010101, %xmm14, %xmm5
xorps %xmm5, %xmm2
movaps %xmm5, 112(%rax)
以上代码采用 gas/AT&T 语法,我的目标是从 Core 2 到 Westmere 的 Intel 处理器,这些处理器提供高达 SSSE3 的指令。
Agner Fog's manuals 之一指出,对于某些用途,使用具有错误“类型”的向量指令可能是有利的。例如,memcpy 使用 movaps 指令编写是有利的,即使要移动的数据不是浮点数,因为 movaps 比 movdqa 短,在更多处理器上可用,并且因为它不计算数据,关于次常态的通常警告都不适用。也给出了相同的建议来改变单词(我之前链接到的手册中的第 13.2 和 13.3 节)。
我的情况有点特殊,因为我打算重构常量向量,如果需要,一些可以仅与单精度“类型”指令一起使用:这些将仅在movaps、shufps 中涉及, xorps 计算。一些常量向量必须参与只能用整数类型指令完成的计算:paddd(因此我可以根据需要使用movdqa、pshufd和pxor指令来保持整数执行域)。
这个问题的一般版本是:考虑到我的目标是 Core 2 和 Westmere 之间的英特尔处理器,我应该分别使用什么类型的指令从内存(重新)加载 xmm14,将其解压缩到寄存器那将只看到单精度计算,将其解压缩到一个寄存器,该寄存器将看到一些单精度指令无法完成的计算,以及后一种情况下可以用单精度指令完成的那些操作?
编辑: harold 在评论中回答了以下问题的一部分。
还有一个包含在一般问题中的更具体的子问题:当我用浮点指令随机替换一些整数执行域指令(例如,movdqa 指令由movaps 指令替换时,是否有人解释了原因? ),函数可以计算错误吗?我预计唯一的后果是执行延迟,而不是错误的结果。
例如,如果在上面我仅将pshufd $0, %xmm14, %xmm4 指令更改为shufps 指令,则计算将完全错误(xmm4 是稍后涉及paddd 的寄存器)。更改其他指令而不是那个会导致其他类型的错误。
【问题讨论】:
-
你不能把
pshufd $0, %xmm14, %xmm4写成shufps。最低的两个花车将来自目的地。 -
@harold 哦。我认为这回答了关于正确性的问题。现在这个问题感觉很傻(我只是问,因为我认为至少正确性方面很有趣)。
-
movdqa->movaps更改是否也破坏了某些东西?那会更有趣,因为它真的不应该 -
@harold 不,我没有看到它破坏任何东西。我真的很困惑,因为
pshufd->shufps更改有时会起作用(在其他情况下源和目标相同)。