1

長い間、私はchar[]ファイルの読み取りと書き込みに単純なバッファーを使用していました。

私が次のような非常に単純な関数を持っていると仮定しましょう:

int f(int fd_in, int fd_out)
{
    char buf[4096];
    char* bufp = buf;
    ssize_t ret, wr;

    ret = read(fd_in, buf, sizeof(buf));
    /* ... */

    while (ret > 0)
    {
        wr = write(fd_out, bufp, ret);
        /* ... */
    }

    return wr;
}

今、私はアライメントの問題をもう少し認識しているので、バッファがにアライメントされるため、これは実際には最適ではないと思い始めていますchar

「より強い」アラインメントを得るために、バッファに別の(より大きな)積分型を使用することは合理的であると思われますか?読み取り/書き込みがより最適になりますか?メリットはどこまで行きますか?posix_memalign整数型がより良い解決策を達成できるよりもさらに多くの整列を得るために使用していますか?

4

1 に答える 1

3
  • memcpy()のコストを過大評価しないでください。現在のマシンでは、memcpyは「バスよりも高速」に実行され、キャッシュスロットが引き込まれるのを待つために多くの時間を費やします。
  • 4096サイズのバッファは、複数のキャッシュスロット(64バイトサイズ、IIRC)にまたがっています。
  • OSにも独自のバッファがあります。(チャンクは、ネットワークバッファから、またはディスクの場合はDMAメモリからコピーする必要があります)
  • 部分的な読み取り+書き込みでは、とにかくねじ込まれます。コードは13バイトを送受信する準備ができています。または133または1333。または4095。または4096。ほとんどの場合、次の読み取り/書き込みは適切に調整されません。良いニュース:とにかく、ディスクファイルの場合、サイズはおそらく512の倍数になります。
  • 2つのシステムコール(読み取り+書き込み)のコストは、memcpyの(整列または非整列)よりもはるかに高くなります(Gray&Reuterの本の表紙の中に推定コストの素晴らしい表があります。少し時代遅れかもしれませんが、それでも非常に有益です)
  • (Linuxの場合)これにはカーネル内のバッファーレス関数(copyfdなど)があります。UPDATE sendfile ()は名前であり、システムコールとして実装されます。
  • いつでも違いを測定することができます:int buff [4096 / sizeof(int)]; 少なくともint-alignedになります。最善の方法は、int配列とchar配列の和集合を使用することです。組合は常に最も気の利いたメンバーの要件に沿っています。
于 2012-09-06T23:01:28.130 に答える