8

私は自分のプログラムで GZIPInputStream を使用していますが、Java でプログラムを並行して実行できれば、パフォーマンスが向上することはわかっています。

一般に、標準 VM を多数のコアで実行するためのコマンドライン オプションはありますか? そのまま1本で動いています。

ありがとう!

編集

Windows XP で普通の Java SE 6 update 17 を実行しています。

GZIPInputStream を別のスレッドに配置すると、明示的に役立ちますか? いいえ!GZIPInputStream を別のスレッドに配置しないでください。マルチスレッド I/O は使用しないでください。

編集 2

同じディスクに読み書きしているので、I / Oがボトルネックだと思います...

一般的に、GZIPInputStream を高速化する方法はありますか? または、並行して実行される GZIPInputStream の代替品ですか?

私が使用した編集3 コードスニペット:

GZIPInputStream gzip = new GZIPInputStream(new FileInputStream(INPUT_FILENAME));
DataInputStream in = new DataInputStream(new BufferedInputStream(gzip));
4

9 に答える 9

16

私の知る限り、このストリームからの読み取りアクションはシングルスレッドであるため、1 つのファイルを読み取る場合、複数の CPU は役に立ちません。

ただし、複数のスレッドを使用して、それぞれが異なるファイルを解凍することもできます。

そうは言っても、最近の解凍は特に計算集約的ではなく、IO のコストによってブロックされる可能性が高くなります (たとえば、HD の 2 つの異なる領域で 2 つの非常に大きなファイルを読み取る場合)。

より一般的には (これが Java の初心者の質問であると仮定すると)、Java は並列処理を行いません。スレッドを使用して、実行したい作業単位とそれらの間の同期方法を伝える必要があります。Java は (OS の助けを借りて) 一般に、利用可能な限り多くのコアを使用し、コアよりも多くのスレッドがある場合 (通常はそうです)、同じコアでスレッドをスワップします。

于 2010-01-01T21:14:12.667 に答える
6

PIGZ = GZipの並列実装は、データを圧縮するときに複数のプロセッサと複数のコアを活用するgzipの完全に機能する代替品です。http://www.zlib.net/pigz/ まだJavaではありません---テイカー。もちろん、世界はJavaでそれを必要としています。

I / Oがボトルネックにならないようにするのに役立ちますが、圧縮または解凍がCPUを大量に消費する場合があります。

HP研究所のデータシリーズ(C ++)も参照してください。PIGZは圧縮を並列化するだけですが、Dataseriesは出力を大きな圧縮ブロックに分割し、並列で解凍できます。他にも多くの機能があります。

于 2010-01-20T22:15:11.573 に答える
2

GZIP ストリームを Buffered ストリームでラップすると、パフォーマンスが大幅に向上します。

OutputStream out = new BufferedOutputStream(
    new GZIPOutputStream(
        new FileOutputStream(myFile)
    )
)

入力ストリームについても同様です。バッファリングされた入出力ストリームを使用すると、ディスクの読み取り回数が減少します。

于 2010-01-01T21:33:42.467 に答える
2

あなたのプログラムの他の処理に対処する答えは見当たりません。

ファイルを解凍するだけなら、単純にコマンド ラインgunzipツールを使用する方がよいでしょう。ただし、そのストリームから引き出すファイルで何らかの処理が行われている可能性があります。

適度なサイズのチャンクで何かを抽出している場合、それらのチャンクの処理は、解凍とは別のスレッドで行われるべきです。

大きな文字列またはその他のデータ ブロックごとにスレッドを手動で開始できます。しかし、Java 1.6 かそこらからは、 のjava.util.concurrentような凝った新しいクラスの 1 つを使用したほうがよいでしょうThreadPoolExecutor


アップデート

Javaを使用してファイルを抽出しているだけかどうかは、質問やその他のコメントからはわかりません。と競合する必要があると本気で考えている場合は、gunzip大きなバッファを使用することでパフォーマンスを向上させることができます。つまり、たとえば 10 MB (10 進数ではなく 2 進数です! - 1048576) のバッファを使用して、それを 1 回で埋めて、同様にディスクに書き込みます。これにより、OS は中規模のディスク スペースの計画を立てる機会が得られ、必要なシステム レベルの呼び出しも少なくなります。

于 2010-01-01T21:45:41.773 に答える
0

複数のVMを実行します。各VMはプロセスであり、パフォーマンスを低下させることなく、コアごとに少なくとも3つのプロセスを実行できる必要があります。もちろん、利益を得るには、アプリケーションがマルチプロセッシングを活用できる必要があります。特効薬はありません。そのため、マルチコアマシンの使用方法がまだわからないという記事がマスコミにうめき声を上げています。

ただし、アプリケーションをマスターに構造化して、ワーカープロセスのプールを管理し、作業パッケージをそれらに分割する人はたくさんいます。すべての問題がこの方法で解決できるわけではありません。

于 2010-01-01T22:42:36.277 に答える
0

マルチスレッド IO が常に悪であると考えるのは間違いだと思います。次の理由から、おそらく特定のケースを確実にプロファイルする必要があります。

  • 最近のオペレーティング システムは、現在空きメモリをキャッシュに使用するため、ファイルを読み取っているときに実際にはハード ドライブにない場合があります。
  • SSD などの最近のハード ドライブはアクセス時間が大幅に高速化されているため、読み取り場所の変更はそれほど問題になりません。
  • この質問は一般的すぎるため、単一のハード ドライブから読み取りを行っているとは想定できません。

切り替えコストを削減するのに十分な大きさにするために、読み取りバッファーを調整する必要がある場合があります。境界のケースでは、すべてのファイルをメモリに読み込み、そこで並行して解凍することができます - より高速で、IO マルチスレッドでの損失はありません。ただし、極端ではないものもうまく機能する場合があります。

また、JRE で利用可能な複数のコアを使用するために特別なことをする必要はありません。異なるスレッドは通常、オペレーティング システムによって管理される異なるコアを使用します。

于 2013-02-09T10:37:45.950 に答える
0

圧縮は並列化の難しいケースのように思えます。これは、圧縮プログラムによって出力されるバイトが、入力の前の W バイト (ここで W はウィンドウ サイズ) の重要な関数であるためです。明らかに、ファイルを断片に分割し、独自のスレッドで実行される断片ごとに独立した圧縮ストリームを作成できます。解凍プログラムがファイルを元に戻す方法を認識できるように、一部の圧縮メタデータを保持する必要がある場合があります。

于 2010-01-01T21:34:23.763 に答える
0

gzip を使用した圧縮と解凍は、シリアル化されたプロセスです。複数のスレッドを使用するには、入力ファイルを多くのストリームに分割するカスタム プログラムを作成してから、それらを解凍して結合するカスタム プログラムを作成する必要があります。いずれにせよ、CPU 使用率がボトルネックになる前に、IO がボトルネックになります。

于 2010-01-01T21:49:42.763 に答える