Fast Memory Copy

for Developer
©2001,2005 XELF. All rights reserved.
since: 2001-01-29
modefied: 2001-01-29
last updated: 2005-09-01 参照先にてご指摘に気づきましたので、ソースコードの関数mem3の間違いを修正しました。

 「メインメモリー間の単純転送でどんな方法が高速か?」という話題がありました。非常に基本的な処理ですが、最近はどんな方法が速いのかということで試してみることにします。

 これについて多数の手法でソースコード「MemoryCopy.cpp」を作成し、ベンチマークをとってみました。
 アセンブラの熟練度はそう高くありませんので、この中にあるコードの一番速いものが、ベストであるとは限りません。よりよいものが出来たら優しくお教え下さればと思います。

ベンチマークの内容について

結果の補足

 VC6の「memcpy」の速度最適化コードは、大きな転送サイズの場合に「rep movsd」を使っていて、「rep movsd」とほぼ同じ結果になっています。

 Pentium MMXの環境では、FPUかMMXで転送するのが速いという結果となっています。このような環境では、長いデータ型が有利なのでしょうか。
 Pentium IIIの環境では、工夫のないFPUやMMXよりも、「rep movsd」が速い結果になっています。命令のデコード時間の分だけ無駄があるのでしょうか。今回の条件でも、ストリーミング・ストア命令のnon temporalは非常に強力で、prefetchも処理を加速し、実験上で最速という結果になりました。

開発環境下での実行結果

(※2001-01-29版での結果です)

Pentium III 600MHz Dual / PC-133

memory copy code benchmark VER.2001-01-29 by (C)2001 XELF.
copy size: 16777216 [bytes]

memcpy: 83.7 [ms]
rep movsd: 83.3 [ms]
FPU 8bytes: 101.5 [ms]
MMX movntq pre 16bytes: 58.8 [ms]
MMX movntq 16bytes: 64.3 [ms]
MMX movntq 8bytes: 64.9 [ms]
SSE movntps pre 32bytes: 57.3 [ms]
SSE movntps 16bytes: 64.4 [ms]
SSE 16bytes: 101.4 [ms]
MMX 16bytes: 101.6 [ms]
MMX 8bytes: 101.0 [ms]
asm 8bytes: 132.8 [ms]
asm 4bytes: 134.8 [ms]
C++ 4bytes: 134.8 [ms]
completed.

Pentium MMX 200MHz

memory copy code benchmark VER.2001-01-29 by (C)2001 XELF.
copy size: 16777216 [bytes]

memcpy: 323.1 [ms]
rep movsd: 317.2 [ms]
FPU 8bytes: 227.4 [ms]
MMX 16bytes: 231.3 [ms]
MMX 8bytes: 227.0 [ms]
asm 8bytes: 316.4 [ms]
asm 4bytes: 316.2 [ms]
C++ 4bytes: 313.6 [ms]
completed.