2013-05-22 1 views
1

예를 들어, 배열 float [] 또는 double []의 두 가지 (길이 2 ~ 3 백만)가 있습니다. 그들을 빨리 추가해야합니다. 그것을하는 방법? 이 라이브러리가 있습니까?Java에서 병렬로 두 개의 배열을 추가하는 방법은 무엇입니까?

+0

다중 스레드를 사용하여 ..., 내가 정말 뭔가를 놓친하지 않는 한 단지 –

+0

을 시뮬레이션 할 수 있습니다. – vikingsteve

+0

당신은 그것을 얼마나 빨리 원하는거야? 난 그냥 만 2 **을 통해 **'double' 값을 루프하고이를 합하는'for' 루프를 썼다. 1 초도 안 걸렸습니다. 그것보다 빨리 필요합니까? – xagyg

답변

2

프로세서 코어 수와 동일한 수의 스레드로 고정 된 스레드 풀을 사용하십시오. 스레드 수만큼의 작업을 제출하십시오. 각 작업은 합계가 필요한 색인 범위를받습니다. 주 스레드에서 모든 Future의 결과를 ExecutorService.submit에서 반환하고 최종 결과를 합산하십시오.

0

배열의 분할을 결정하고 N 개의 스레드가 배열의 지정된 부분을 읽고 개별 합계를 찾도록하는 방법이 있습니다. 최종 스레드는 최종 출력을 위해 이러한 모든 개별 합계를 더할 수 있습니다.

0

나는 많은 진정한 고성능 코딩을 할 수 없었했지만 최적화의 여지가 여기에 (내가 순진 해요하지 않는 한) 각각 n 개의 세그먼트로 목록 (1 나누는 것 외에는 전혀 없습니다 코어) 각각의 코어에 부분합이오고 부분합을 추가하게하십시오. 이제 당신이 가치를 배가하도록 요청 받았다면, 근로자가 0을 만회하자마자 당신은 당신의 답을 얻습니다.

public class ArrayAdder { 
    public double getTotal(double[] array) { 
     Worker workers[] = new Worker[Runtime.getRuntime().availableProcessors()]; 
     for (int i = 0; i < workers.length - 1;i++) { 
      workers[i] = new Worker(array, 
        i * array.length/workers.length, 
        (i + 1) * array.length/workers.length); 
     } 
     workers[workers.length - 1] = new Worker(array, 
       (workers.length - 1) * array.length/workers.length,array.length); 
     double total = 0; 
     for (int i = 0;i < workers.length;i++) { 
      try { 
       workers[i].join(); 
       total += workers[i].getSum(); 
      } catch (InterruptedException e) { 
       i--; //retry the wait for worker[i] 
      } 

     } 
     return total; 

    } 
    static class Worker extends Thread { 
     public Worker(double[] array, int start, int end) { 
      super(); 
      this.array = array; 
      this.start = start; 
      this.end = end; 
      start(); 
     } 
     private double[] array; 
     private int start; 
     private int end; 
     private double sum; 
     @Override 
     public void run() { 
      for (int i=start;i < end;i++) { 
       sum += array[i]; 
      } 

     } 
     public double getSum() { return sum; } 
    } 
} 

당신은 당신이 값이 될 것으로 기대 얼마나 큰지에 따라 BigDecimal로 합계 총을 저장할 수 있습니다. 물론, 정확한 답이 필요하다면 ints/longs로 추가하는 것이 훨씬 빠를 것입니다. - 그냥 캐스팅하거나 캐스팅하지 않고 (빠른 것일 수 있습니다) 반올림하고 싶을 것입니다. ~ array.length/2 시간이 지나면 캐스트가 잘못된 방향으로 "돌립니다".

0

Java7에서 Fork/Join 프레임 워크를 사용하십시오.

0

또 다른 가능한 최적화는 부분적으로 루프를 줄이기하여 CPU의 슈퍼 스칼라 능력을 사용하려고 할 수 있습니다. 네 INT의 파이프 라인 크기 (JVM이 지능 인 경우) 예를 들어

, 아키텍처에, 당신은 쓸 수 :

for(int i = 0; i < array.size(); i += 4) 
{ 
    c[i] = a[i] + b[i]; 
    c[i+1] = a[i+1] + b[i+1]; 
    c[i+2] = a[i+2] + b[i+2]; 
    c[i+3] = a[i+3] + b[i+3]; 
} 

하지만 당신은 모든 다른 아키텍처의 파이프 라인 크기에 대해 서로 다른 코드를 작성해야 .

관련 문제