4

処理する必要がある巨大なバイト配列があります。理論的には、作業を均等にスライスして別のスレッドに割り当て、マルチコア マシンでのパフォーマンスを向上させることができるはずです。

ByteBuffer各スレッドに を割り当て、それぞれデータの一部を処理しました。8 つの論理プロセッサを使用しているにもかかわらず、最終的なパフォーマンスはシングル スレッドよりも遅くなります。また、非常に矛盾しています。場合によっては、同じ入力の処理が 2 倍以上遅くなることがあります。何故ですか?データは最初にメモリにロードされるため、それ以上のIO操作は実行されません。

MappedByteBufferより高速であるため、次を使用して ByteBuffers を割り当てますByteBuffer.wrap()

public ByteBuffer getByteBuffer() throws IOException
{
    File binaryFile = new File("...");
    FileChannel binaryFileChannel = new RandomAccessFile(binaryFile, "r").getChannel();

    return binaryFileChannel.map(FileChannel.MapMode.READ_ONLY, 0, binaryFileChannel.size());
}

私は以下を使用して並行処理を行いますExecutors

int threadsCount = Runtime.getRuntime().availableProcessors();
ExecutorService executorService = Executors.newFixedThreadPool(threadsCount);
ExecutorCompletionService<String> completionService = new ExecutorCompletionService<>(executorService);

for (ByteBufferRange byteBufferRange : byteBufferRanges)
{
    Callable<String> task = () ->
    {
        performTask(byteBufferRange);

        return null;
    };

    completionService.submit(task);
}

// Wait for all tasks to finish
for (ByteBufferRange ignored : byteBufferRanges)
{
    completionService.take().get();
}

executorService.shutdown();

並行タスクperformTask()は、独自のByteBufferインスタンスを使用して、バッファーからメモリを読み取り、計算を実行します。それらは互いに同期したり、書き込みをしたり、影響を与えたりしません。何がうまくいかないのか、またはこれは並列化の良いケースではないのでしょうか?

同じ問題が存在しByteBuffer.wrap()ますMappedByteBuffer

4

1 に答える 1

2

@EJP が述べたように、ディスクは実際にはマルチスレッドではありませんが、SSD が役立つ場合があります。バッファをマッピングするポイントは、自分でメモリを管理する必要がないようにすることです。仮想メモリマネージャーとファイルシステムキャッシュは、Javaのヒープに移動するよりも高速であり、おそらくあなたが作成するメモリ管理コードよりも高速であるため、OSに任せてください。

処理を本当に並列化できる場合は、単一のスレッドでファイル全体を読み取り、チャンク (おそらく何らかの中間データ形式) に分割してから、エグゼキュータにこれらのチャンクで作業させる方がよいでしょう。ファイル読み取りスレッドは他のスレッドと同時に実行できるため、処理を開始するためにファイル全体を読み取る必要はありません。

cores - 1ファイル読み取りスレッドを枯渇させないように、executor の数を に設定してみてください。これにより、OS はファイル読み取りスレッドをコンテキスト切り替えなしで単一のコアで実行し続けることができるため、他のコアを使用して CPU を集中的に使用する作業を実行しながら、優れた IO パフォーマンスを得ることができます。

参考までに、これが Apache Spark の目的です。大きなファイルを処理する必要がある場合や、単一のシステムよりも高速に処理する必要がある場合は、これを参照してください。

于 2016-06-04T01:54:01.000 に答える