* gcc-4.x の SIMD 命令サポート その2 [#ae8cd212]
新しいマシンを買い,Linux マシンが Celeron D にグレードアップしてしまいました.
というわけで,今回は SSE/SSE2 について.

** SSE レジスタ [#a1f8ecee]
SSE では 128 ビット長の''専用''レジスタを 8 本新設しています.
つまり,[[前回>日記/2008-09-03/gcc-4.x での SIMD 命令サポート]]の 3DNow! とは違い,x87 演算と分離する必要はありません.

で,レジスタの中身ですが,SSE レジスタ 1 本に
- SSE では 32bit 単精度 (float) 型を 4 本
- SSE2 では 64bit 倍精度 (double) 型を 2 本

を格納し,SIMD 演算を行うことができます.

** 参考文献 [#n4e9b777]
参考となる書籍など.

- gcc-4.3 の info
-- SIMD 命令の gcc 上の取扱いについて書いてあります.
- [http://developer.intel.com/products/processor/manuals/index.htm Intel® 64 and IA-32 Architectures Software Developer's Manuals]
-- インテルの web サイトにある,IA-32 アーキテクチャのマニュアルです.SSE/SSE2 については Volume I に書いてあります.
- [http://www.amazon.co.jp/dp/4789833429 x86アセンブラ入門―PC/ATなどで使われている80x86のアセンブラを習得]
-- CQ 出版社から出ている本.もちろん日本語です.

** おおまかな枠組み [#ea83c11a]
前回と一緒で

+ SIMD のレジスタにあった型の変数を定義して
+ ビルトイン関数で演算を記述
+ -mXXX オプションを付けてコンパイル

です.


** 型宣言 [#ud57c751]
まずは SSE での「単精度 x 4 本」の構成の変数の型宣言から.

 typedef float v4sf __attribute__ ((vector_size(16))) __attribute__((aligned(16)));

前回と違っておしりに

 __attribute__((aligned(16)))

なんて属性がついてますね.
これは
> 変数を割り当てるアドレスを 16 で割り切れるアドレスにせよ

という属性です.
これは,実は SSE レジスタのロード・ストア時においてこの様な制限があるために,このような属性を追加しています.
この制限を無視するとどうなるかというと,Segmentation fault が発生します.
ARM や MIPS などの変数のアラインメントと似たような感じです.

ここで 1 つ注意.この aligned(16) 属性は
 v4sf a;
のような変数の宣言では有効に機能しますが
 v4sf *a = malloc ( sizeof(v4sf) );
のような動的メモリ割り当てではうまく働きません.また
 float a[2];
 *(v4sf *)&a[0] = b;
のようなキャストもだめです.
つまり,既に割り当てられている領域を「16 で割り切れるアドレスに配置換え」する力はありません.

トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS