連載1 高速なメモリーコピー その3
メモリーには一定のバイト毎に区切りを示す境界がありまして、その区切りをまたぐ読み書きのアクセスを行うと大体半分くらいまで処理速度が低下してしまいます。
理由は判りませんが、何となく境界の前方と後方の両ブロックに対して処理しなければいけないとかそんなふうに私は理解しています。
また、SSE命令の場合は境界をまたいだアクセスが許されている命令と、アクセスが許されていない命令がありまして、許されていない命令で(境界をまたいだ)アクセスを行うとプログラムは強制終了されると言ったペナルティーまであります。
さらに、境界の間隔は命令(セット?)によって変わってきます。最初に示しましたmemcpy()の場合は2バイトか4バイト毎の境界となるようです(ちょっとどっちか判らないですが)、それに対してSSE命令は16バイト(128bit)毎と丁度レジスタのサイズと同じ間隔で境界が設定されています。
このような理由から高速な処理を行おうとした場合、どの命令を使うにしても結局アライメントは揃えないとベストな結果は得られないので、「高速なメモリーコピー処理」の肝は如何にしてアライメントをそろえるかと言う話に終始します。
アライメントさえ揃えてしまえば後は前回の「MOVDQAで128bit読み込んでちょこちょこっとやってMOVNTDQで書き込む」だけで簡単にベストな結果が得られます。
なんだそんなの簡単じゃんって思う方もいらっしゃると思いますが今回はここまで、続く...
「MOVNTQならアライメント制限なし」これはどうですか?とコメントを頂きました。
この命令はMMXレジスタを使ってメモリに書き込みを行う「書き込み専用命令」で、MOVNTDQと同様?にキャッシュを汚染しないのが特徴のようですね。
また、MMX全般に言えますがアライメントによる制限を受けずその点がMOVNTDQと異なるのでそこに利点があるかどうかでしょうか(って頂いたコメントのまんまですね^^
ちょっと比較したことが無いので結論は先送りさせていただきますが(今度AMV2コーデックを作るときに試してみようと思います)、エラーは出ないけど境界をまたいだ処理は遅くなるであろうという予測と、SSEレジスタを使った命令が全般的に高速化されていて、MMXを2命令使うよりSSEを1命令で済ませた方が速度面で期待できる(これはIntel系(core2duo以降?)のみです。
AMD系(Athlon64X2)ではMMXニ個とSSE一個がほぼ同じ時間で処理されるようです)という2点から見込みは薄いと思います。
- 関連記事
trackback
コメントの投稿