2013년 1월 10일 목요일

특정 코드를 병렬로 수행하기 - Java

Scala 는 scala.collection.parallel._ 에 ParArray 등 병렬 처리를 지원하는 자료구조가 지원됩니다만, Java 7 까지는 직접적으로 지원하지는 않습니다.

그래서 Java 로 유사하게 Data 처리를 병렬로 수행할 수 있도록 하는 코드를 구현해 봤습니다.

private static int getPartitionSize(int itemCount, int partitionCount) {
    return (itemCount / partitionCount) + ((itemCount % partitionCount) > 0 ? 1 : 0);
}

다음과 같은 절차로 수행됩니다.

  1. ExecutorService 생성 - 논리적 CPU 갯수만큼의 작업스레드를 가지게 한다.
  2. 입력 데이터 컬렉션인 elements 를 Process 갯수로 나눈다. (partitions)
    각 Process 별로 작업할 컬렉션을 분할합니다. ( Process 가 4개이고, elements 수가 100개라면, 0~24 : 0 CPU, 25~49 : 1 CPU ... )
  3. partition 별로 작업을 정의한다. 
  4. 모든 작업을 ExecutorService에게 실행시킨다.
  5. 작업 결과를 취합하여 반환한다.

위의 코드가 아주 제한적인 기능이지만, 입력값 별로 특정 로직을 수행할 때에는 유용합니다. 기본적으로 CPU가 4개라면, 최대 4배까지 빨라집니다. 물론 부가 작업이 있으니 약간은 떨어지겠지요.

만약 집계 기능의 경우는 위의 3, 4 번에서 소계를 수행하는 코드와 마지막 집계하는 코드가 더 필요할 것입니다.

테스트 코드는 다음과 같습니다. 십만번 호출 작업을 하는 테스트 코드 블럭을 100번 반복할 때, CPU 갯수 만큼 나눠서 수행하도록 합니다.


* 소스 중에 컬렉션 관련 메소드는 Google Guava 13.0 을 사용했습니다.

댓글 없음: