« 炎を入れてあれこれ | メイン | PhotoShop のファイルからレイアウトを取り込む »

2008年03月06日

x86 SIMD Technique:: ハイブリッド データ オーダー

    

SIMD を使わない場合、以下のような構造体の配列 ( AoS ) を使うことが多いと思う。

struct Vector { float x, y, z; };
Vector vec[100];

でも、この形だと垂直演算が基本の SIMD では扱い辛い。
そこで、SIMD で処理する場合、データ構造は以下のような配列の構造体 ( SoA ) を使うと思う。

struct Vector {
__declspec(align(16)) float x[100], y[100], z[100];
};

ただ、配列サイズが大きくなるとメモリページの再オープンが発生して速度が低下するらしい。
この境界は一般的に 4KB だとか。
そこで AoS と SoA の両方を併せ持ったデータ構造にすることでより効率的に処理できるようになる。

struct Vector {
__declspec(align(16)) float x[8], y[8], z[8];
};
Vector vec[15];

ここで、要素数を 8 としているのは、キャッシュ・ラインのサイズである 32バイトにあわせるため ( キャッシュ・ラインのサイズは CPU によって異なるとか。 ) 。
ただ、横方向に1個ずつずらしながら処理する必要がある場合など、この方法が取り辛い場合もある。
その場合は、キャッシュ・ラインのサイズやメモリページのブロックサイズなどを考えて工夫しないといけない。

詳しくは、インターネット・ストリーミングSIMD 拡張命令を考慮したアプリケーション・チューニング ( PDF ) に載っている。
と言うか、これを読んだ方がわかりやすい。



投稿者 Takenori : 2008年03月06日 03:34




comments powered by Disqus
Total : Today : Yesterday : なかのひと