連載1 高速なメモリーコピー その2
確かにキャッシュの制御も超重要なポイントとなりますね。ありがとう御座います。という事で、ポイントは一つ増えて3つです。
・SSE命令を使う
・メモリーアライメントを制御する
・キャッシュを制御する
で、最初のSSE命令ですが私が扱えるSSE2命令までだと次の3つがあります。
命令 | 読み・書き | アライメント | 備考 |
MOVDQU | 両方可 | そろえる必要なし | 制限のゆるい汎用命令。 |
MOVDQA | 両方可 | そろえる必要あり | アライメントの制限がある代わりに早いらしい。 |
MOVNTDQ | 書き込みのみ可 | そろえる必要あり | アライメント制限に加え、書き込みのみの専用命令。 |
何れも128bitを一度に処理できますが、制限が厳しいものほど高速に動作するらしいです。厳密なデータは取っていませんが、私のAthlon64X2だと、MOVDQUをMOVDQAに代えてもあまり効果は得られない印象ですが、MOVDQAの書き込みをMOVNTDQに代えると30%くらいは早くなった気がします。
なので、「MOVDQAで128bit読み込んで、MOVNTDQで書き込む」というのを繰り返していくのが理想となります。
但し、この2つの命令はメモリーアライメントの制約がありまして、単純にmemcpyの代わりにはなってもらえません。
また、MOVNTDQが高速な理由と言うのが、「キャッシュを使わずに書き込みを行う※」という事らしいので早速3つ目のポイントも出てきます。
メモリーアライメントについては次回書くとして、キャッシュ制御について先に書いちゃいますね。
キャッシュ制御には読み込みを高速化するプリフェッチ(先読み)と、上記の様に書き込みを高速化するものがあります。
そこで、読み書き両方を高速化したらベストなのかなと考えますが、どうも違うようです。理由は現在のパソコンの事情から読み込み処理より書き込み処理の方が時間がかかる(ハードウエアの都合で理論上2倍の時間がかかるのかな、この辺は自信がありませんがベンチマークテストすると大体2倍くらい違いますよね)ので、プリフェッチにより読み込みを高速化しても書き込み処理が追いつかず、結局読込み処理は(書き込み処理が終わるまで)待たされてしまうことになるからです。
いきなり結論になってしまいますが、私は書き込み速度で頭打ちされているなと感じたので結局メモリーコピーでプリフェッチは行わないことにしました。
ちなみに、プリフェッチは書き込みよりも読み込みに負担がかかるハーフサイズ処理で大きな効果がありました(Athlonの場合だけの高速化、且つ、アライメントの問題で結局アマレココには採用しませんでしたが)。
続く...
※キャッシュの汚染を最小にとどめる・・・と言う解説なので、キャッシュを絶対に使わないってわけではないかもしれません。キャッシュの事は気にしないで書き込みだけなら誰にも負けない高速な命令と私は理解しています。
- 関連記事
trackback
コメントの投稿