在Mac OS X上,通过引用或值传递向量是否更有效?

时间:2013-05-16 22:33:11

标签: macos clang simd calling-convention

Clang有一个C / C ++扩展,允许您将矢量值视为一等公民:

typedef double double4 __attribute__((ext_vector_type(4));
// easy assignment
double4 a = {1, 2, 3, 4};
double4 b = {4, 3, 2, 1};
// basic operators work component-wise
double4 c = a + b; // {5, 5, 5, 5}
// you can even swizzle elements!
double4 d = a.zyxw; // {3, 2, 1, 4}

我相信这些载体会利用底层平台的SIMD指令(Intel Mac上的SSE,ARM上的NEON)。但是,我不太确定Mac OS调用约定如何处理矢量类型。

通过引用或复制传递向量会更有效吗?差异可能不大,但由于我将传递很多载体,我想我可能会尽快找到正确的习惯。

1 个答案:

答案 0 :(得分:1)

快速测试表明,在您的示例double4中,参数在堆栈上传递,但在寄存器xmm0和xmm1中返回。这有点奇怪。另一方面,float4个参数在寄存器xmm0中传递到xmm7,结果以xmm0的形式返回,正如您所期望的那样。

Apple使用 System V应用程序二进制接口。适用于Mac OS X的AMD64架构处理器补充。。如果我正确解释该文档,所有内容都应该在寄存器中传递。我不确定clang在这里做什么。也许这仍在进行中,未来可能会发生变化?如果他们这样做,当你试图混合新旧行为时,它可能会破坏你的程序。

对于性能,使用clang传递每个值的向量不是问题。如果你的功能不是很短,那么应该没有明显的区别。如果你确实使用非常小的函数,你应该试图说服编译器内联它们(例如通过声明它们static)。

编辑:关于AVX扩展:如果启用它们,编译器使用寄存器ymm0到ymm7作为参数,使用ymm0作为结果。在这种情况下,double4占用一个ymm寄存器而不是xmm寄存器对。