2

情報のブロックを含むバイナリファイルがあります(以降、これらをパケットと呼びます)。各パケットは、固定長のヘッダーと可変長の本文で構成されます。パケットヘッダー自体から本文の長さを決定する必要があります。私の仕事は、ファイルからこれらのパケットを読み取り、それらに対して何らかの操作を実行することです。現在、私はこのタスクを次のように実行しています。

  • ファイルをランダムアクセスファイルとして開き、特定の開始位置(ユーザー指定の開始位置)に移動します。この位置から最初のパケットを読み取ります。特定の操作を実行する
  • その後、ループで
    • 次のパケットを読む
    • 操作の実行これは、ファイルの終わりマーカーに到達するまで続きます。

ご想像のとおり、ファイルサイズが大きい場合、各パケットを順番に読み取って処理するのは時間のかかる作業です。どういうわけか、この操作、つまりパケット生成操作を並列化してブロッキングキューに入れ、キューから各パケットを並列に取得して操作を実行したいと思います。

誰かがこれらのパケットを並行して生成する方法を提案できますか?

4

3 に答える 3

5

ファイルが単一のドライブにあると想定しているため、ファイルを順番に読み取るスレッドは1つだけにする必要があります。ファイルの読み取りは IO 速度によって制限されるため、CPU で並列化しても意味がありません。実際、通常のハード ドライブはシーケンシャル IO 用に設計されているため、ノンシーケンシャルに読み取るとパフォーマンスが大幅に低下します。読み込むパケットごとに、そのオブジェクトをスレッドセーフなキューに入れる必要があります。

これで、パケットの処理の並列化を開始できます。複数のスレッドを作成し、それぞれがキューからパケットを読み取るようにします。各スレッドは処理を実行し、それを「終了」キューに入れる必要があります。

IO スレッドがファイルの読み取りを終了したら、フラグを設定して、キューが空になると作業中のスレッドが停止するようにする必要があります。

于 2012-06-19T22:30:18.840 に答える
3

プラッター付きのディスク (つまり、SSD ではない) を使用している場合、複数のスレッドでファイルを読み取っても意味がありません。これは、ディスクをスラッシングするだけで、ディスク アームにミリ秒の遅延が発生するためです。SSD をお持ちの場合は別の話であり、読み取りを並列化できます。

代わりに、ファイルからデータを読み取り、パケットを作成する 1 つのスレッドを用意してから、次のことを行う必要があります。

  • 共有セマフォ 'A' を待機します (これは、'max buffered packets' カウントとなる数値に初期化されています)
  • 共有オブジェクトをロックする
  • パケットを LinkedList に追加する
  • 別の共有セマフォ 'B' にシグナルを送ります (これはバッファ内のパケット数を追跡​​しています)

次に、他の多くのスレッドで次のことを行うことができます。

  • 「B」セマフォで待機する (処理するパケットがあることを確認するため)
  • 共有オブジェクトをロックする
  • LinkedList で getFirst() を実行し、パケットをローカル変数に格納します
  • 別のパケットをバッファリングされたパケットリストに入れることを許可する信号セマフォ「A」

これにより、パケットを 1 つの連続シーケンスでストライピングすることにより (プラッター ディスクから) 可能な限り高速にパケットを読み取ることができ、ポーリングなしで一度に複数のパケットを処理することが保証されます。

于 2012-06-19T22:35:14.183 に答える
0

既知の高速な方法は java.nio.MappedByteBuffer を使用していると思います

于 2012-06-19T22:24:28.970 に答える