在 Mac OS X 上,通过引用传递向量还是通过值传递向量更有效?
Posted
技术标签:
【中文标题】在 Mac OS X 上,通过引用传递向量还是通过值传递向量更有效?【英文标题】:On Mac OS X, is it more efficient to pass vectors by reference or by value? 【发布时间】:2013-05-16 22:33:11 【问题描述】: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 指令(英特尔 Mac 上的 SSE,ARM 上的 NEON)。但是,我不太确定 Mac OS 调用约定如何处理向量类型。
通过引用或复制传递向量会更有效吗?差异可能不会很大,但由于我会传递很多向量,我想我可能会尽快养成正确的习惯。
【问题讨论】:
SSE 寄存器是 128 位宽,但double4
是 256 位宽。
@DietrichEpp,据我了解,AVX 带来了 256 位 ymm0
-ymm15
寄存器(xmm
现在指的是低 128 位)。
AVX 默认不启用。
@DietrichEpp 由什么启用? Mac OS X 从 10.6.8 开始支持它们。如果只是编译器切换的问题,那听起来还不错。
对。我就是这个意思。默认不启用,必须使用-mavx
编译器标志。
【参考方案1】:
快速测试表明,在您的示例中,double4
参数在堆栈上传递,但在寄存器 xmm0 和 xmm1 中返回。这有点奇怪。另一方面,float4
参数在寄存器 xmm0 到 xmm7 中传递,结果在 xmm0 中返回,正如您所期望的那样。
Apple 使用System V 应用程序二进制接口。 AMD64 架构处理器补充。 适用于 Mac OS X。如果我正确解释该文档,则所有内容都应在寄存器中传递。我不确定clang在这里做什么。也许这仍在进行中,将来可能会改变?如果他们这样做了,当您尝试混合新旧行为时,它可能会破坏您的程序。
为了性能,使用 clang 传递每个值的向量不是问题。如果您的功能不是非常短,则应该没有明显的区别。如果您确实使用了非常小的函数,您应该尝试说服编译器内联它们(例如,通过声明它们 static
)。
编辑:关于 AVX 扩展:如果启用它们,编译器将使用寄存器 ymm0 到 ymm7 作为参数,使用 ymm0 作为结果。在这种情况下,double4 占用单个 ymm 寄存器,而不是 xmm 寄存器对。
【讨论】:
如何在xmm0
中返回?它是必要宽度的一半。
@zneak 一个 float4 是 128 位,并且适合 xmm0。 double4 为 256 位,在寄存器对 xmm0 和 xmm1(缩写为 xmm0/1)中返回。以上是关于在 Mac OS X 上,通过引用传递向量还是通过值传递向量更有效?的主要内容,如果未能解决你的问题,请参考以下文章
无法在 Mac OS X 上通过 jinfo 启用 DTrace 探测