大規模な流れの差の数をすばやく計算するには?

大規模な流れの差の数をすばやく計算するには?

2つの大きなストリーム(デバイス/ファイル)の違い(異なるバイト)数を計算したいと思います。たとえば、2つのハードドライブまたは1つのハードドライブと/dev/zero

関連するプログラムは入力ストリームと同じくらい高速でなければなりません(たとえば、1 GB / s、0.2 GB / sでも動作する可能性があります)、最大数GBのRAMおよびtmpファイルを使用できます。特に、計算する違いを保存するのに十分なファイルシステムがありません。これらのストリームのサイズは数テラバイトです。

計算では、スペースや改行文字を他の文字とは異なる方法で処理する必要はなく、実際には処理できません。これらのストリームはバイナリ専用なので、テキストとして解釈することはできません。

ストリームについて話していますが、これらのデバイスは実際に検索可能です。ただし、速度上の理由で可能であれば、クエリなしで1つのストリームですべての操作を実行するのが最善です。

私が今まで試したこと:

cmp -l /dev/sda /dev/sdb | wc

しかし、これは遅すぎます。wc1つのCPUコアのみ50%以上使用すると、出力は約2MB/sに過ぎず、100倍も遅くなります。

ベストアンサー1

検索可能ファイルを使用すると、これを並列化できます。たとえば、次のことができます(テストされていません)。

# Number of jobs to run at once
jobs=4
# Block size
bs=512
# Total number of block to work with
size=1000000
# Or, to calculate the size automatically for one of the disks,
#size=$(( $(df -B 1 /dev/sda | tail -n1 | awk '{ print $2 }') / $bs ))

# Number of blocks per job
count=$(( $size / $jobs )) 
for i in $(seq 1 $jobs) ; do
    seek=$(( ($i - 1) * $count ))
    cmp -l <(dd bs=$bs skip=$seek count=$count if=/dev/sdb1) <(dd bs=$bs skip=$seek count=$count if=/dev/sdb2) | wc &
done

ddif は最初の起動時に一度だけ検索されます。

おすすめ記事