거대한 바이트 배열을 처리해야합니다. 이론 상으로는 멀티 코어 머신에서 성능을 높이기 위해 작업을 조각으로 나누어 다른 스레드에 할당 할 수 있어야합니다.멀티 스레드 ByteBuffers는 순차적으로 느립니까?
각 스레드에 대해 ByteBuffer
을 할당하고 각각 데이터의 처리 된 부분을 할당했습니다. 8 개의 논리 프로세서가 있어도 최종 성능은 단일 스레드보다 느립니다. 또한 그것은 매우 일치하지 않습니다. 때로는 동일한 입력이 처리 속도가 느린 경우보다 두 배 이상 길 때가 있습니다. 왜 그런가요? 데이터가 먼저 메모리에로드되므로 더 이상 IO
작업이 수행되지 않습니다. 이 ByteBuffer.wrap()
보다 빠른 때문에
나는 MappedByteBuffer
를 사용하여 내 ByteBuffer의 할당 :
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
인스턴스를 사용
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
를 사용하여 내 동시 처리를 할 버퍼에서 계산 등을 수행합니다. 그들은 서로 동기화, 쓰기 또는 영향을주지 않습니다. 어떤 아이디어가 잘못되었거나 이것이 병렬화의 좋은 경우가 아닐까요?
ByteBuffer.wrap()
과 MappedByteBuffer
도 같은 문제가 있습니다.
배열의 크기는 얼마나됩니까? – Logan
매핑 된 버퍼는 실제로 파일이 메모리에로드되지 않습니다. OS는 파일 내용을 읽으면 파일 내용의 청크 (페이지)를 메모리에 동적으로 매핑하고 다른 곳에서 읽으면 다른 데이터에 대한 데이터를 바꿉니다. 메모리에 테라 바이트가있는 것처럼 보이지만 실제 메모리는 거의 사용하지 않습니다. 그러나 점프를하면 디스크에서 다시 읽어야 할 수도 있습니다. – zapl
@LoganKulinski : 몇 가지 100MB – BullyWiiPlaza