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