今回は宿題となっていたmmx命令の
movntqについて試してきました。この命令は連載の中で紹介したsse命令の
movntdqと似た働きをしますが、一度に処理できるデータ量が8バイトと少ない代わりにアライメントの制約を受けないと言うメリットがあります。この辺のメリットとデメリットがどう作用するかを試してきました。
check | アライメント | パソコン2 Celeron |
| | memcpy() | ssememcpy() | mmxmemcpy() |
check1 | (dst+0, src+0) | 1076 MB/s | 1594 MB/s | 1524 MB/s |
check2 | (dst+1, src+0) | 473 MB/s | 1580 MB/s | 1400 MB/s |
check3 | (dst+0, src+1) | 898 MB/s | 1578 MB/s | 1534 MB/s |
check4 | (dst+1, src+1) | 709 MB/s | 1600 MB/s | 1288 MB/s |
check5 | (dst+3, src+2) | 460 MB/s | 1584 MB/s | 1288 MB/s |
※
memcpy()は連載1-7回のデータをそのまま転載しています。
| パソコン2 Celeron |
CPU | Intel Celeron 420 (Conroe-L) 1.6GHz Socket 775LGA |
Chipset | i945G/GZ |
Memory | DDR2, 1GB (single) read=3.3GB/s write=1.2GB/s |
OS | Windows2000 Pro SP4 |
補足 | デスクトップPC |
mmxmemcpy()が
movntqを使ったメモリーコピー処理となり、メモリーのアライメントは一切そろえずひたすらmovqで読込んで
movntqで書き込んでいきます。
一方ssememcpy()は以前と同じものです。全ての条件でアライメントを揃えて処理しています。なお、memcpy()は今回データを取っていないので前回のものをそのまま記載しています。
全体的に見てmovntqは予想以上に良い結果となりました。アライメントが揃っているcheck1ではssememcpy()に肉薄していますし、書き込みのアライメントのみ揃っているcheck3でも肉薄しています。check2,4,5では恐らく書き込み側のアライメントが揃っていないためにパフォーマンスが低下していますが、memcpy()と比べるとパフォーマンスの低下は低く良好な結果だと思います。
最後になりますが、きっちりアライメントを揃えてからsseの専用命令を使うのがベストですが、sse命令が使えない、レジスターが足りない、プログラムをシンプルにしたいなどの理由からmmxを使った処理も十分検討に値すると思いました。
次回からは「コーデックを使った画像転送システム」を紹介いたします。ファンタジーリモートの心臓部とも言える重要な部分ですが実はとっても簡単です。コーデックに関するドキュメントなどググってもあまり出てこないのでその辺を意識した連載にしたいと思っています。
- 関連記事
-