1

dd を使用してストリームをディスクにコピーするループがあります。速度上の理由から、プロセス全体で「bs」を使用してより大きなブロックサイズを使用しています。ただし、ある特定の行では、'ibs' と 'obs' を使用する必要があります。これは、'seek' の場所が、他の場所で使用する 'bs' の倍数ではないためです。

私の質問は: dd または他のプログラム/Perl モジュールを使用して、「シーク」に使用されるものとは異なるブロックサイズを書き出す方法はありますか?

dd if=/dev/ram1 of=/dev/sdb1 seek=2469396480 ibs=1048576 obs=1 count=1

上記のように、生データは 1M ブロックで読み取られますが、バイト単位の粒度に基づいて特定の場所をシークする必要があるため、1 バイト セグメントで書き出す必要があります。これにより、書き込み速度が 1/100 になります。

回避策はありますか? または、dd を使用せずに Perl でこれを行う方法はありますか?

ありがとう、

ニック

4

1 に答える 1

0

この問題は に固有のものですdd。目的のシーク位置に適切な大きさの係数がない場合 (良好なパフォーマンスを得るには十分な大きさですが、バッファー サイズとして使用するには十分に小さい)、行き詰まります。これは、目的のシーク位置が大きな素数である場合に特に発生します。

この特定のケースでは、Mark Mannが指摘したように、適切な選択肢があります

これを一般的に行うには、 以外のものを使用する必要がありますdd。幸いなことに、ddさんのタスクは非常に単純で、必要なのは次のコードだけです (疑似コードで...私はしばらく Perl をあまり使っていません)。

if = open("/dev/ram1", "r")
of = open("/dev/sdb1", "r+")
seek(of, 2469396480)
loop until you have copied the amount of data you want {
    chunk = read(if, min(chunksize, remaining_bytes_to_copy))
    write(of, chunk)
}

コピーのソースは、ある種の ramdisk のようです。本当に最高のパフォーマンスが必要な場合は、チャンクをバッファーに読み込んでバッファーを出力ファイルに書き出す以外の別の方法を試すことができます。たとえばmmap()、ソース ファイルをwrite()マッピング アドレスから直接取得できます。OS は、RAM から RAM へのコピー操作の 1 つを最適化する (またはしない) 場合があります。そのようなメソッドは移植性が低く、Perl のような高級言語で使用できる可能性が低いことに注意してください。

于 2012-01-05T17:51:55.410 に答える