2012-12-25 2 views
2

저는 MPI를 배우기위한 프로그램을 작성하고 있습니다. 좋아, 나는 사각형 행렬을 곱하는 프로그램을 만들 것이다.mpiun이없는 프로그램은 매우 느립니다.

long **multiplyMatrices(long **matrix1, long **matrix2, long capacity) 
{ 
    long **resultMatrix = new long*[capacity]; 

    for (long i = 0; i < capacity; ++i) { 
     resultMatrix[i] = new long[capacity]; 
    } 

    for (long i = 0, j, k; i < capacity; ++i) { 
     for (j = 0; j < capacity; ++j) { 
      resultMatrix[i][j] = 0; 

      for (k = 0; k < capacity; ++k) { 
       resultMatrix[i][j] = resultMatrix[i][j] + matrix1[i][k] * matrix2[k][j]; 
      } 
     } 
    } 

    return resultMatrix; 
} 

여기서 capacity == 1000.

로컬 호스트 (Mac Mini 2012, Core i7, OS X 10.8.2)에서이 코드를 LLVM을 사용하는 XCode로 컴파일합니다. 계산에는 17 초가 소요됩니다. 네, 하나의 스레드에서. 원격 호스트

(일 OS 5.11, 듀얼 코어 CPU 8의 vCPU)는 I는 mpirun main 계산할 152 초가 소요 ...

g++ -I/usr/openmpi/ompi-1.5/include -I/usr/openmpi/ompi-1.5/include/openmpi -O2 main.cpp -R/opt/mx/lib -R/usr/openmpi/ompi-1.5/lib -L/usr/openmpi/ompi-1.5/lib -lmpi -lopen-rte -lopen-pal -lnsl -lrt -lm -ldl -lsocket -o main 

하거나

g++ -O2 main.cpp -o main 

하지만 그것을 컴파일 이 ... 뭐가 잘못 됐니? 내가 놓친 게 있니? 그것은 서버의 CPU 아키텍처에 관한 것입니까?

답변

0

주된 대답은 메모리 관리입니다.

long **resultMatrix = new long*[capacity]; 

for (long i = 0; i < capacity; ++i) { 
    resultMatrix[i] = new long[capacity]; 
} 

모든 라인 전체가 아닌 블록으로 메모리의 다른 장소에있는 그 선에서

봐. 우리는 물리적 메모리가 Mac Mini - 2 개의 플라스틱에 어떻게 표시되는지는 알고 있지만 서버에서는 다른 호스트 (클러스터) 일 수도 있습니다.

이제 문제를 해결해 보겠습니다.

long **allocateMatrix(long capacity) 
{ 
    // Allocating a vector of pointers to rows 
    long **matrix = (long **)malloc(capacity * sizeof(long *)); 

    // Allocating a matrix as a whole block 
    matrix[0] = (long *)malloc(capacity * capacity * sizeof(long)); 

    // Initializing a vector of pointers with rows of addresses 
    long *lineAddress = matrix[0]; 
    for(long i = 0; i < capacity; ++i) { 
     matrix[i] = lineAddress; 
     lineAddress += capacity; 
    } 

    return matrix; 
} 

void deallocateMatrix(long **matrix, long capacity) 
{ 
    free(matrix[0]); 
    free(matrix); 
} 

이렇게하면 Mac mini에서 실행되는 코드가 서버에서 9.8 초 (58 초)로 향상됩니다.

그러나 나는 아직도 다른 시간 누수가 어디에 있는지 알지 못합니다. 어쩌면 내가 어떻게 든 루핑 하나를 최적화해야합니다.