web-dev-qa-db-ja.com

ハッシュがCPUにバインドされている場合、巨大なファイルのアイデンティティをどのようにチェックしますか?

小さなファイルの場合、ハッシュは問題ありませんが、大きなファイルでは簡単に見つけることができますmd5sumはCPUバウンドです。複数のコアでスケールアウトできるハッシュアルゴリズムはありますか?回避策はありますか?アイデア?何か? :)

7
poige

私の現時点での最善策は次のとおりです。

parallel --block=512M --pipepart -a …HUGEFILE… --progress --recend '' \ -k -j …NUMofProcessesSay4… md5sum | md5sum

- 注意すべきこと:

  1. 結果のmd5ハッシュはファイルではなく、その一部のmd5のハッシュですが、レプリカがOriginと同一であるかどうかを比較できます
  2. また、特にpipeを使用し、入力としてfileを使用しない場合は、パフォーマンスがあまりよくありません
  3. parallel--pipepart私が知ったように、ディスクパーティションをサポートしていません

他の方法も聞いてみたいです。

14
poige

残念ながら、MD5は線形プロセスであり、その状態は以前のすべての入力に依存します。つまり、それを真に並列化することはできません。さらに、この方法で動作しない実際のハッシュ代数については知りません。

あなたができること(そしてあなたの答えに基づいてあなたがやっていること)は、ソースファイルを分割し、各チャンクのmd5sumを同時に計算することです。

それができない、またはできない場合は、 xxHashCityHash または SpookyHash のような高速なハッシュ関数を使用する必要がありました。

他のアイデア(多分それはあなたの意図的な用途に適用可能です):MD5よりも高速なものが必要な場合(シングルスレッドですが)、MD5に頼って、最初の高速パスにCRC32(最近のCPUによってハードウェアアクセラレーション)を使用できます。/SHA1は一見同一のファイルの2番目のパスです。

4
shodanshok

ファイル全体の処理を回避することはほとんどありません。 MD4またはCRC32はおそらく、広く展開されている高速なアルゴリズムに最適です(ただし、CRC32はMD4よりもはるかに効果が低くなります)。

選択したアルゴリズムのさまざまな実装をテストすると役立ちます。十分にテストされたasm実装を見つけることができれば、C/C++のいとこのパフォーマンスが向上する可能性があります。

相互運用性をあまり気にしない場合は、ファイルをチャンクに分割して(ディスク上で実行する必要はなく、特定のオフセットから読み取りを開始するだけです)、各チャンクを個別に処理することで、複数のコアにまたがるハッシュを簡単に実行できます。 (ただし、これにより深刻なディスクスラッシングが発生し、特にメカニカルディスクのパフォーマンスが低下します)。最終的にはチャンクごとに別々のハッシュになります(これには、壊れたチャンクにポイントするなど、他の利点もあります)が、常に1つの最終的な値にハッシュすることができます。

これ Gistは、Pythonで何かを始めるのに適しています。

2
Gary

私はツリーハッシュプロジェクトに取り組んでいます。これは、まさにこの問題のために設計されています。大きなファイルの既成の並列ハッシュです。まだレビューされていませんが、現在は機能しています。レビューからの変更によって最終的なダイジェストが変更される可能性は十分にあります。とはいえ、それは非常に高速です: https://github.com/oconnor663/bao

0
Jack O'Connor

ここでの回答のほとんどは、ほとんどのハッシュアルゴリズムの線形性に対処しています。確かにスケーラブルなハッシュアルゴリズムがいくつか存在することは確かですが、より簡単な解決策は、データを小さな断片に分割し、それぞれを個別にハッシュすることです。

BitTorrentアプローチを検討してください。Torrentが作成されると、すべてのファイルが「ブロック」に分割され、各ブロックが個別にハッシュされ、各ハッシュが.torrentファイルに記録されます。これにより、最初にファイル全体のダウンロードが完了するのを待たずに、ピアが受信データを段階的に検証できます。エラーは、ファイル全体を再送信する代わりに、ブロックごとに修正することもできます。ロジスティクス上の利点の他に、このアプローチでは、複数のコアにまたがってハッシュを拡張できます。8つのコアが利用可能な場合、8つのブロックを同時にハッシュできます。

検証プロセスを設計して、データの一部のサブセット(たとえば、一部の固定サイズのブロックでは、各ブロックを個別のコアでハッシュできるため、パイプラインでの大量の遅延を排除できます。明らかに、このアプローチには小さな時間とメモリのトレードオフがあります。ハッシュのインスタンスが追加されるたびに、それに関連するオーバーヘッドがほとんどメモリの形で発生しますが、数百のインスタンスを実行している場合を除き、これは最小限です。

0
tfrederick74656