0

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 の呼び出し規則がベクトル型をどのように扱っているかはよくわかりません。

ベクトルを参照またはコピーで渡す方が効率的ですか? 違いはそれほど大きくないかもしれませんが、多くのベクトルをやり取りするので、できるだけ早く正しい習慣を身につけることができると考えました.

4

1 に答える 1

1

簡単なテストでは、この例でdouble4は引数がスタックに渡されますが、レジスタ xmm0 および xmm1 に返されることがわかります。これは少し奇妙です。float4一方、引数は xmm0 から xmm7 までのレジスターに渡され、結果は xmm0 に返されます。

Apple はSystem V Application Binary Interface を使用しています。AMD64 アーキテクチャ プロセッサ サプリメント。そのドキュメントを正しく解釈すると、すべてがレジスタに渡されるはずです。ここでclangが何をしているのかわかりません。多分これはまだ進行中の作業であり、将来変更される可能性がありますか? その場合、古い動作と新しい動作を混在させようとすると、プログラムが壊れる可能性があります。

パフォーマンスのために、clang で値ごとにベクトルを渡すことは問題ではありません。関数が極端に短くない場合、顕著な違いはないはずです。非常に小さな関数を使用する場合は、コンパイラにそれらをインライン化するように説得する必要があります (たとえば、関数を宣言することによってstatic)。

編集: AVX 拡張機能について: それらを有効にすると、コンパイラは引数にレジスタ ymm0 から ymm7 を使用し、結果に ymm0 を使用します。その場合、double4 は、xmm レジスターのペアではなく、単一の ymm レジスターを占有します。

于 2013-05-17T00:12:59.060 に答える