gcc 4.1.2 ではvec_ld()
、CPU MPC74XX のボードでは正しく動作しません。
float temp[4];
__vector float Src;
Src = (__vector float)vec_ld(0, temp);
ただし、float 変数が 16 バイトにアラインされている場合は、正しく機能します。
float temp[4] __attribute__((aligned(16)));
これは設計によるものですか?
はい、AltiVec のロードとストアには 16 バイトのアラインメントが必要です。これは、AltiVec のマニュアルに詳しく記載されています。
ただし、SSE などの他の SIMD アーキテクチャとは異なり、AltiVec は、例外を生成するのではなく、アラインされていないアドレスを次の下位 16 バイト境界に静かに切り捨てるため、コードがクラッシュすることはありませんが、ロードまたはストアしようとすると正しく動作しません。アラインされていないアドレスで。
アラインされていないロードを回避できない場合は、2 つの隣接するアラインされたベクトルをロードしてから、 vec_lvsl
+vec_perm
を使用して必要なベクトルを作成できます。
float temp[4];
__vector float sr1, src2, src;
src1 = vec_ld(0, temp);
src2 = vec_ld(16, temp);
src = vec_perm(src1, src2, vec_lvsl(0, temp));
ところで、Power8 では、アンアライン ロード/ストア ベクトル アクセスのサポートがついに追加されました。詳細については、Power ISA 2.07ドキュメントのセクション「7.6 VSX Instruction Set」のlxvd2x
/lxvw4x
およびstxvd2x
/命令に関する情報を参照してください。stxvw4x
IBM XL C/C++ Compilerにアクセスできるユーザーは、 vec_xld2()
/vec_xlw4()
およびvec_xstd2()
/vec_xstw4()
組み込み関数を使用できます。
バージョン "g++ (GCC) 4.10.0 20140419 (experimental)" の時点で、GCC に相当するものを認識していませんが、GCC のユーザーは、ポインター逆参照によってアライメントされていないメモリにアクセスできると思います。
signed int *data;
// ...
vector signed int r = *(vector signed int *)&(data[i]);