2013-10-16 1 views
0

차원 10,000 x 10,000의 두 행렬의 행렬 곱셈을 수행해야합니다. 각 요소는 범위 1에서 10,000까지 무작위로 생성됩니다. 스레드 (25 개 스레드)와 스레드없이 수행하고 시간을 비교해야합니다. 간단한 행렬 곱셈 알고리즘 O (n^3)을 사용하고 있습니다. 스레드가없는 프로그램은 (하루 이상) 영원히 실행되었으며 스레드를 실행하려고하면 스레드 된 버전이 중단됩니다. 그것은 1000 X 1000 매트릭스행렬 곱셈 10000 X 10000

내 대학 서버 여기 에 CC의 prog.cc -lpthread -lposix4를 사용하여 컴파일을 위해 잘 작동되지 않은 스레드 버전의

/* 컴파일러 : 유닉스 서버

이 프로그램은 스레드가없는 두 개의 10000 * 10000 행렬의 행렬 곱셈을 수행합니다. 이 프로그램의 목적은 스레드를 사용하지 않는 것에 대해 스레드 을 사용하여 다른 데이터에서 동일한 계산을 수행하는 성능 향상을 시연하는 것입니다. 여기

#include <pthread.h> 
#include <iostream.h> 
#include <semaphore.h> 
#include <unistd.h> 
#include<math.h> 

int main() 
{ 
    double **A;//Matrix A 
    double **B;//Matrix B 
    double **C;//Output Matrix C 
    const int MATRIX_DIMENSION = 5000; 

    //Assign Matrix A first dimension 
    //----------------------------------------------------------- 
    A = new double*[MATRIX_DIMENSION]; 
    //Assign second dimension 
    for(int i = 0; i < MATRIX_DIMENSION; i++) 
    { 
     A[i] = new double[MATRIX_DIMENSION]; 
    } 
    //Assign Matrix B first dimension 
    B = new double*[MATRIX_DIMENSION]; 
    //Assign second dimension 
    for(int i = 0; i < MATRIX_DIMENSION; i++) 
    { 
     B[i] = new double[MATRIX_DIMENSION]; 
    } 
    //Assign Matrix C first dimension 
    C = new double*[MATRIX_DIMENSION]; 
    //Assign second dimension 
    for(int i = 0; i < MATRIX_DIMENSION; i++) 
    { 
     C[i] = new double[MATRIX_DIMENSION]; 
    } 
    //----------------------------------------------------------- 

    //Generate random numbers for matrices A and B and assign C to 0 
    for(int i=0;i<MATRIX_DIMENSION;i++) 
    { 
     for(int j=0;j<MATRIX_DIMENSION;j++) 
     { 
      A[i][j] = rand() % 10000; 
      B[i][j] = rand() % 10000; 
      C[i][j] = 0; // initialize C to zero 
     } 
    } 
    //----------------------------------------------------------- 
    //Do the matrix multiplication 

    for(int i=0;i<MATRIX_DIMENSION;i++) 
    { 
     for(int j=0 ;j<MATRIX_DIMENSION; j++) 
     { 
      for(int k=0;k<MATRIX_DIMENSION;k++) 
      { 
       C[i][j]+=A[i][k]*B[k][j]; 
      } 
     }                                                                                   
    }        

    //----------------------------------------------------------- 
    //delete the dynamic memory of A 
    for (int i = 0; i < MATRIX_DIMENSION; i++) 
    { 
     delete[] A[i]; 
    } 
    delete[] A; 
    //delete the dynamic memory of B 
    for (int i = 0; i < MATRIX_DIMENSION; i++) 
    { 
     delete[] B[i]; 
    } 
    delete[] B; 
    //delete the dynamic memory of C 
    for (int i = 0; i < MATRIX_DIMENSION; i++) 
    { 
     delete[] C[i]; 
    } 
    delete[] C; 
    //----------------------------------------------------------- 
    return(0); 
} 

*/

는 스레드 버전의 /* 이름 : 컴파일러 : 유닉스 서버

이 프로그램은이 프로그램의 목적이다 스레드 없이 두 10000 * 10000 행렬의 행렬 곱셈을 수행한다 스레드를 사용하여 다른 데이터에 대해 동일한 계산을 수행하는 스레드를 사용하지 않는 경우의 성능 향상을 보여줍니다. */

#include <pthread.h> 
#include <iostream.h> 
#include <semaphore.h> 
#include <unistd.h> 
#include<math.h> 

//Global variables 
    double **A;//Matrix A 
    double **B;//Matrix B 
    double **C;//Output Matrix C 
    const int MATRIX_DIMENSION = 10000; //We need a 10000 X 10000 Matrix 
    const int NUM_THREADS = 25; // One thread completes 1/25th of the work 
    const int THREAD_DIMENSION = MATRIX_DIMENSION/NUM_THREADS; //Array that each thread will operate on 
    pthread_t * thread[NUM_THREADS]; 

    /*************************************************************************** 
    Function that does matrix multiplication of 1/25th of the whole matrix, 
    The division is done by dividing the Matrix into row's all 1/25 of the total matrix 
    Each row of Matrix A operates on all the columns of Matrix B to get corresponding elements of Matrix C 
    Parameter : arg, this is used as and index for which part of the Matrix this particular thread operates on 
    Return type: void 
    ****************************************************************************/ 
void *MatrixMul (void * arg) 
{ 
    int index; 
    index = (int) arg; 
    int operation_Lower_Limit = ((index+1) * THREAD_DIMENSION) - THREAD_DIMENSION ; //Multiplication starting row 
    int operation_Upper_Limit = ((index+1) * THREAD_DIMENSION) - 1; //Multiplication ending row 

    for(int i=operation_Lower_Limit;i<=operation_Upper_Limit;i++) //only 1/25th of Matrix A is used 
    { 
     for(int j=0 ;j<MATRIX_DIMENSION; j++) // The whole B matrix is used 
     { 
      for(int k=0;k<MATRIX_DIMENSION;k++) 
      { 
       C[i][j]+=A[i][k]*B[k][j]; 
      } 
     }                                                                                   
    } 
    return NULL; 
} 

int main() 
{ 

    srand(time(0)); 
    //Assign memory for threads 
    for(int i=0;i < NUM_THREADS;i++) 
    { 
    thread[i] = new pthread_t; 
    } 

    //Assign Matrix A first dimension 
    //----------------------------------------------------------- 
    A = new double*[MATRIX_DIMENSION]; 
    //Assign second dimension 
    for(int i = 0; i < MATRIX_DIMENSION; i++) 
    { 
     A[i] = new double[MATRIX_DIMENSION]; 
    } 
    //Assign Matrix B first dimension 
    B = new double*[MATRIX_DIMENSION]; 
    //Assign second dimension 
    for(int i = 0; i < MATRIX_DIMENSION; i++) 
    { 
     B[i] = new double[MATRIX_DIMENSION]; 
    } 
    //Assign Matrix C first dimension 
    C = new double*[MATRIX_DIMENSION]; 
    //Assign second dimension 
    for(int i = 0; i < MATRIX_DIMENSION; i++) 
    { 
     C[i] = new double[MATRIX_DIMENSION]; 
    } 
    //----------------------------------------------------------- 



    //Generate random numbers for matrices A and B and assign C to 0 
    for(int i=0;i<MATRIX_DIMENSION;i++) 
    { 
     for(int j=0;j<MATRIX_DIMENSION;j++) 
     { 
      A[i][j] = rand() % 10000; 
      B[i][j] = rand() % 10000; 
      C[i][j] = 0; // initialize C to zero 
     } 
    } 
    //----------------------------------------------------------- 
    //Do the matrix multiplication 

    for(int i=0;i<NUM_THREADS;i++) 
    { 
    pthread_create(thread[ i ], NULL, (MatrixMul), (void *) (i)); 
    } 


    //wait for all the threads to complete execution 
    for(int i=0;i<NUM_THREADS;i++) 
    { 
    pthread_join(*thread[i],NULL); 
    } 

    //----------------------------------------------------------- 
    //delete the dynamic memory of A 
    for (int i = 0; i < MATRIX_DIMENSION; i++) 
    { 
     delete[] A[i]; 
    } 
    delete[] A; 
    //delete the dynamic memory of B 
    for (int i = 0; i < MATRIX_DIMENSION; i++) 
    { 
     delete[] B[i]; 
    } 
    delete[] B; 
    //delete the dynamic memory of C 
    for (int i = 0; i < MATRIX_DIMENSION; i++) 
    { 
     delete[] C[i]; 
    } 
    delete[] C; 
    //----------------------------------------------------------- 
    return(0); 
} 
+0

어떤 시스템을 실행하고 있습니까? – DashControl

+0

@DashControl 퍼티를 사용하는 대학 유닉스 서버에 원격 연결이 있습니다. –

답변

0

프로그램 메모리가 부족합니까? 그렇다면 승수를 수행하면서 메모리 일부를 비울 수 있습니까?

+1

답장을 보내 주셔서 감사합니다. 하지만 메모리가 부족하면 분할 오류가 발생하지 않습니까? –

+0

@AjayKarthik 그것은 단지 추측이지만, 하나의 10000x10000 행렬을 할당하는 것이 약 7Gb가 될까요? 그리고 그 중 3 개 (!)를 할당하고 있습니다. –

+0

변수를 int 유형으로 변경했습니다. 이제는 각각 약 1.5GB가 있어야하며 총 4.5GB입니다. 나는 4GB 램이있는 로컬 우분투 컴퓨터에서 스레드없이 곱셈을 실행 중입니다. 그러나 OS가 virutal memory를 올바르게 사용하기 때문에 이것은 문제가되어서는 안된다. 프로그램은 지금 약 5 시간 동안 실행되었습니다. 제 교수는 사형 집행을 완료하는 데 훨씬 오래 걸릴 것이라고 말했습니다. 나는 그것이 어떻게 가는지 볼 것이다. 감사합니다. –