【问题标题】:How to force GCC to pass 128bits/256bits struct as function param in xmm/ymm register?如何强制 GCC 将 128bits/256bits 结构作为 xmm/ymm 寄存器中的函数参数传递?
【发布时间】:2013-12-25 05:43:07
【问题描述】:

如何强制 GCC 将 128bits/256bits 结构作为函数参数传递到 xmm/ymm 寄存器中? IE。如果我的结构是 256 位宽(UnsignedLongLongStruct 下面)

(我知道如果我使用内在函数来制作压缩整数,gcc 足够聪明,可以将它放入 %ymm 寄存器,但我可以用 struct 来做吗?)

typedef struct {
   unsigned long long ull1;
   unsigned long long ull2;
   unsigned long long ull3;
   unsigned long long ull4;
} UnsignedLongLongStruct;

void func1( UnsignedLongLongStruct unsignedLongLongStruct ) {
....
}

【问题讨论】:

  • 先对齐上个世纪,用C++!
  • 你确定这是个好主意吗?如果函数需要将值作为单独的标量,将它们放入调用者中的 ymm reg 并在被调用者中再次取出将比以正常方式传递它们更昂贵,即使这意味着它们必须进入堆栈,因为使用所有可用的参数传递寄存器。

标签: gcc struct 64-bit parameter-passing avx


【解决方案1】:

TL;DR:调用约定似乎明确提到了 __m256 和要放在 umm regs 中的朋友。

X86-64 System V ABI,第3.2.3点,你可以检查参数是如何传递的。我的阅读是只有__m256 参数将被转换为一个 SSE 和 3 个 SSEUP 8 字节块,这允许它们在 ymm 寄存器中传递。

这将使您的参数在内存中传递,这就是我们在 clang、gcc 和 icc 中看到的:Test program on godbolt

为了将它作为寄存器传递,在我阅读调用约定时,您似乎必须将它作为 __m256(或其变体)传递。

【讨论】:

    【解决方案2】:

    不同平台和编译器的调用约定有点混乱。您应该将输入按值作为__m256 传递给您的函数。

    如果它是一个微不足道的函数并且您想确保 GCC 内联它,您可以使用 always_inline 属性声明它以避免任何不必要的加载/存储:

    inline __attribute__((always_inline)) __m256 foo(__m256 const input);
    

    【讨论】:

    • 如果你使用always_inline,那么乱用__m256i是没有意义的;只需传递结构。内联的代码将以编译器所能想到的最有效的方式使用它。
    猜你喜欢
    • 2014-08-19
    • 2021-11-13
    • 2016-02-15
    • 1970-01-01
    • 2020-05-04
    • 2013-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多