代码之家  ›  专栏  ›  技术社区  ›  Ian Boyd

如何将两个压缩的64位四字加载到128位xmm寄存器中

  •  2
  • Ian Boyd  · 技术社区  · 6 年前

    我有两个UInt64(即64位四字)整数。

    • 它们与一个8字节的字符对齐( sizeof(UInt64) )边界 (我也可以将它们对齐到16字节,如果这对任何事情都有用的话)
    • 它们被打包在一起,因此它们在记忆中并排出现

    如何将它们加载到xmm寄存器中,例如。 xmm0 :

    enter image description here


    movq xmm0, v[0]
    

    但这只会让人感动 v[0] ,并在中设置高64位 xmm0

    xmm0 0000000000000000 24FC18D93B2C9D8F

    奖金问题

    • 我怎样才能把它们弄出来?
    • 如果它们在记忆中不是并排的呢?

    编辑

    如W。Chang指出,endiannessification很小,我同意相反的说法:

    enter image description here

    我的难题是如何让他们进来和出去。

    1 回复  |  直到 6 年前
        1
  •  6
  •   Peter Cordes    4 年前

    即使两个四字跨缓存线边界分割,这通常也是吞吐量的最佳选择(在AMD CPU上,如果负载不适合缓存线的32字节对齐块,而不仅仅是64字节缓存线边界,则可能会受到惩罚。但在英特尔,64字节缓存线内的任何错位都是免费的。)

    如果您的加载提供整数SIMD指令,您可能需要 movdqu movups 机器代码短1字节。一些CPU可能关心不同类型负载的“域交叉”。对于存储,这并不重要,许多编译器总是使用 移动


    另见 How can I accurately benchmark unaligned access speed on x86_64

    移动 即使16个字节都来自同一缓存线,速度也很慢,您可以使用

    • movq xmm0,[v0] :
    • movhps xmm0, [v0+8] : 移动高压缩单精度浮点

    movhps 效率略高于 SSE4.1 pinsrq xmm0, [v1], 1 movhps 是1个微熔合uop,但仍然需要相同的后端端口:load+shuffle。

    请参阅Agner Fog的x86优化指南;他有一章是关于SIMD的,其中很大一部分是关于数据移动的。 https://agner.org/optimize/ 并查看中的其他链接 https://stackoverflow.com/tags/x86/info .


    为了把数据拿回来, 移动 你可以像商店一样工作,你也可以 movlps / movhps 把单词分成两半(但不要使用 莫沃尔普斯 movq movsd .)

    莫沃尔普斯 比1字节短 莫沃 ,但两者都可以将xmm寄存器的低位64位存储到内存中。编译器经常忽略存储的域交叉(vec int vs.vec fp),所以您也应该这样做:通常使用SSE1 ...ps 说明,当它们与商店完全相同时(不适用于注册移动;尼哈勒姆可以放慢速度 movaps 在整数SIMD-like之间 paddd ,反之亦然。)

    双重的 对于实际的加法/乘法指令以外的任何指令,都没有带有独立CPU的CPU 浮动 双重的 绕过转发域。ISA设计保留了这个选项,但实际上,使用 莫瓦普斯 . 或使用 莫沃尔普斯 而不是 movlpd 洗牌有时很有用,因为 unpcklpd 就像 punpcklqdq unpcklps punpckldq (交错32位元素)。

    推荐文章