パスワードを忘れた? アカウント作成
1347 story

最適なメモリー・コピーの方法 13

ストーリー by Oliver
長さ指定忘れてバッファオーバフロー 部門より

takusi 曰く,"develより。LinuxとWindowsにおけるメモリー・コピーの性能の違いを測定したものです。下のほうにMS-Excelのグラフがあるのですが、Linuxが特に面白いグラフになっています。もしかしたら測定の方法に問題があったのかもしれません。皆さんのPCでの結果を、是非、教えてください。"

ハードウェアの機能をうまく使っているからこそ、揺らぎが出るとは面白い。

この議論は賞味期限が切れたので、アーカイブ化されています。 新たにコメントを付けることはできません。
  • 素朴な疑問だが (スコア:3, 参考になる)

    by brake-handle (5065) on 2001年10月22日 15時23分 (#31566)

    MBオーダのメモリのコピーが欲しい場合、mmap(2)で別のアドレス空間に見かけ上コピーする(必要ならばMAP_PRIVATEでcopy-on-writeを併用)方がずっと速そうだし、ページの節約もできると考えてしまうのは私だけだろうか?

  • by nekopon (1483) on 2001年10月22日 15時39分 (#31571) 日記
    mmap(2)は alignment の問題がありそーな気がするのは気のせいですかしら? (たとえばpixel imageの転送とかだと使えない可能性のほうが大きいですよね?)
  • おまけで (スコア:2, 参考になる)

    by ShibaQ (2782) on 2001年10月22日 21時28分 (#31714)
    char*の指す領域をdoubleで指すとMiss Alignmentで落ちるCPUがあります。RISC系の石はほんとそうでしょう。 仮に落ちないとしても、8byte(処理系によっちゃ4byteあり)にアラインされていないdouble型のデータを アクセスしようとするとメモリアクセスが2回行われたりする(x86がそう)ので、キャストを使ったメモリコピーはパフォーマンス上の問題を抱えることがあります。

    mallocでとる領域は、常にその処理系で扱う最大bit長をもつ基本データ型と同じアライン値にする場合が多いので、ミスアラインに気づかないこともあったり。昔のわたしがそうでした。ハイ。

  • Re:要するに (スコア:2, 参考になる)

    by Mc.N (3705) on 2001年10月23日 0時06分 (#31782) 日記
    「FreeBSD 徹底入門」と言う本に記載されていた「i586_bcopy 問題」を思い出しました。確か浮動小数点レジスタを使用した 8byte momory copy は通常の copy より速かったという理由だったような。結局 Pentium 以外の CPU(Cyrix、PentiumPro)で問題が多発したから止めたらしいです。

    もしそれを狙ったコーディングなら、ちとセンスが古いような気がします。
    --
    Mc.N
  • gccのバージョンが2.96になってますな。
    #gccの正式リリースではなく、RedHatが無理に組み込んだ開発版。

    そこまでは気づけなかったのかなぁ・・・まぁ、これは
    RedHatを選択したのがまずかったですね。

    従って、これはRedHat7.0とWin2kでの比較記事ですね。

    #前よかちょっとはマシになってるものの、相変わらず
    #詰めが甘いようですな・・・残念なことに(汗)。
    --
    ---- redbrick
  • by seldon (5637) on 2001年10月22日 19時34分 (#31643)
    char/int/long/doubleなどでコピーする場合は一度になるだけ大きなサイズでコピーできるのを選んだ方が速い
    memcpyは約1kbyte程度を越えるあたりからなら他の方法より速い(場合が多い)
    という、当然と言うかあたりまえというか予測可能な結論が出ただけのような気もする。

    まぁ、memcpyなんかでバラ付きが出るってのはちょっと面白いけどね。

    だけど、いくら速いからと言っても

    char buffer_from[1024], buffer_to[1024];
    double *sptr = (double*)buffer_from, *dptr = (double*)buffer_to;
    int count;

    for(count=0; count<128; count++) {
       *dptr++ = *sptr++;
    }

    とかってcharのものをdouble*でコピーするなんてのはマトモな神経ではないような気が...
    今時のCPUの速度とか考えれば、やっぱり微妙な速度差よりはソースの読みやすさを優先すべきだと思うけどなぁ

    私的には、

    • Allocationした型(サイズ)でコピーする
    • ちょっと大き目の領域とか、structならmemcpy
    って感じで使い分けてるかなぁ?
  • 今時のCPUの速度とか考えれば、やっぱり微妙な速度差よりはソースの読みやすさを優先すべきだと思うけどなぁ
    多少、オフトビかと思います。私も、殆どのケースで、メモリ・コピーはmemcpyで十分だし、自分でmemcpyを使わないでメモリ・コピーをする必要はないと思います。

    今回のトピックは、コピーの方法によって、どのような速度の違いがでるのか、OSやコンパイラの違いによって、どのような違いがでるのか、という話だと思います。
    --
    rm -rf /bin/laden
  • by minz (3213) on 2001年10月22日 20時08分 (#31662) ホームページ 日記
    > double *sptr = (double*)buffer_from, *dptr = (double*)buffer_to;

    ライブラリも使わんと、一バイト、二バイト、四バイト、八バイト転送をこれだけでやってるヤツをクビにしたことあります (^^;

    特に double * なんてのは、途中に正規化補正その他の変換命令が出てしまったとしても、コンパイラにはモンクいえませんです。はい。

    --
    みんつ
  • by satomako (6195) on 2001年10月22日 21時27分 (#31713)

    両方ともIntelコンパイラ使ったらどうなんでしょうね?

    --
    BURRN!
  • by Mc.N (3705) on 2001年10月23日 0時27分 (#31791) 日記
    それなら Windows も VirtualAlloc() に書き換えるとずっとパフォーマンスが上がるような気がします。

    そもそも今回の目的は Windows と Linux の source が同じであることに意味があるらしいので敢えて CRT を使っているのではないかと。

    興味深いのですが参考になるかと言われると、、、どうなんでしょうか?
    --
    Mc.N
  • そうですね、興味あるところですねぇ。
    後、Win32でもcygwin使ってどちらもgccベースで試すとか面白そうですよね。

    #しかし、大元の記事読んだら、これって前のpipeのものより
    #前の記事でやんの(汗)。
    #pipeの記事は思いっ切り手抜きだったんだな・・・。
    --
    ---- redbrick
  • mmap(2)的な手法は確かに、スレッド間のstaticなコピーには使えますが、元を残して 複製を加工する場合には使えないと思うのですが。
    複製したデータの塊から加工したデータを同じ領域に書き換える場合とか、却ってメモ リ効率が悪くなる場合もある。
    つまりは、mmap(2)的な手法が使えない場合ってのは結構多いのではないかと思うので すが。

  • by tmiura (6268) on 2001年10月25日 14時37分 (#32591) 日記

    でこぼこが出るのはループ最適化でよくあるプロローグとエピローグの影響ってことで。

    機械語レベルで考えると、複数の命令でできたループを回すよりもストリング命令ひとつの方がだいぶ速かったってことですよね。 逆にいうと、よくチューンされたmemcpy関数はだからストリング命令を使ってると。

    コンパイラレベルでは、ループを認識してストリング命令まで落とし込んでくれるようなやつがまだいない、と。

typodupeerror

長期的な見通しやビジョンはあえて持たないようにしてる -- Linus Torvalds

読み込み中...