2014-01-15 2 views
0

Итак, вот моя проблема. Я написал код умножения матрицы C++ последовательно и параллельно. Я хочу рассчитать время, которое требуется для выполнения каждого из них. Другими словами, выход должен выглядеть следующим образом:C++ ctime.h не будет правильно рассчитать время

«Последовательное время умножения: #### секунд».
«Параллельное время умножения: #### секунд».

Но проблема, с которой я столкнулся, - это запустить этот код на машине linux. Он отлично работает на окнах, но мне нужно запустить этот код в Linux. Когда я запускаю код, его серийное время умножения дает мне значение, но параллельное время дает мне более высокие значения, но работает быстрее. Например, я запускал матричное умножение с двумя матрицами каждые 1000х1000. Серийное время составляло 9 секунд, а параллельное время составляло 18 секунд, но для завершения вычисления потребовалось не более половины времени. Некоторое время я ждал окончания серийного умножения, но параллельное умножение закончилось сразу с некоторым неправильным значением за прошедшее время. Вот мой код:

#include <iostream> 
#include <omp.h> 
#include <time.h> 
#include <stdlib.h> 
using namespace std; 

int  RowA; 
int  ColA; 
int  RowB; 
int  ColB; 
clock_t  PTime = 0; 
clock_t  STime = 0; 

double**  MatA; 
double**  MatB; 
double**  MatC; 

void  CreateMatrix(); 
void  PopulateMatrix(); 
void  S_MultiplyMatrix(); 
void  P_MultiplyMatrix(); 

int main() 
{ 
    cout << "Enter Size of Matrix A: "; 
    cin >> RowA >> ColA; 
    cout << "Enter size of Matrix B: "; 
    cin >> RowB >> ColB; 

    if (ColA == RowB) 
    { 
     CreateMatrix(); 
     PopulateMatrix(); 

     STime = clock(); 
     S_MultiplyMatrix(); 
     STime = clock() - STime; 
     cout << "Serial Matrix Multiplication time: " << STime/CLOCKS_PER_SEC << " seconds. " << endl; 

     PTime = clock(); 
     P_MultiplyMatrix(); 
     PTime = clock() - PTime; 
     cout << "Parallel Matrix Multiplication time: " << PTime/CLOCKS_PER_SEC << " seconds. " << endl; 
    } 
    else 
    { 
     cout << "Matrix Dimensions do not agree!!" << endl; 
    } 
    return 0; 
} 


void CreateMatrix() 
{ 
    MatA = new double*[RowA]; 
    for (int i=0; i<RowA; i++) 
    { 
     MatA[i] = new double[ColA]; 
    } 

    MatB = new double*[RowB]; 
    for (int i=0; i<RowB; i++) 
    { 
     MatB[i] = new double[ColB]; 
    } 

    MatC = new double*[RowA]; 
    for (int i=0; i<RowA; i++) 
    { 
     MatC[i] = new double[ColB]; 
    } 
} 


void PopulateMatrix() 
{ 
    for (int i=0; i<RowA; i++) 
    { 
     for (int j=0; j<ColA; j++) 
     { 
      MatA[i][j] = rand() & 10 + 1; 
     } 
    } 

    for (int i=0; i<RowB; i++) 
    { 
     for (int j=0; j<ColB; j++) 
     { 
      MatB[i][j] = rand() & 10 + 1; 
     } 
    } 
} 


void S_MultiplyMatrix() 
{ 

    for (int i=0; i<RowA; i++) 
    { 
     for (int j=0; j<ColB; j++) 
     { 
      for (int k=0; k<ColA; k++) 
      { 
       MatC[i][j] += MatA[i][k]*MatB[k][j]; 
      } 
     } 
    } 

} 


void P_MultiplyMatrix() 
{ 
    #pragma omp parallel for //default(none) shared(MatA, MatB, MatC, RowA, ColB, ColA) 
    for (int i=0; i<RowA; i++) 
    { 
     #pragma omp parallel for 
     for (int j=0; j<ColB; j++) 
     { 
      double temp = 0; 
      for (int k=0; k<ColA; k++) 
      { 
       temp += MatA[i][k]*MatB[k][j]; 
      } 
      MatC[i][j] = temp; 
     } 
    } 
} 

Пожалуйста, помогите понять это! Я понятия не имею, почему он не будет правильно подсчитывать время в Linux. Как я уже сказал, у меня нет проблем в окнах, но мне нужно запустить это в Linux, потому что у меня большие вычисления матрицы, которые нужно запускать на кластере Linux и точно записывать время!

Спасибо!

JD

+0

Во-первых, поддерживает ли ваш Linux-компилятор OpenMP? –

+0

18 секунд времени процессора не обязательно означают 18 секунд времени настенных часов - тем более, что вы измеряете параллелизированный код. –

+0

Да, мой компилятор поддерживает OpenMP. – user2863626

ответ

4

Функция clock фактически измеряет время, которое вы активно проводите на процессоре, а не на время стены. Это не очень полезно в вашем случае, потому что он измеряет комбинированное время процессора для всех потоков, и обычно это больше, чем время стены.

Если вам не нужно высокое временное разрешение, вы можете использовать функцию time, которая измеряет время стены, но имеет одно второе разрешение. Если вам нужно более точное время, вы можете взглянуть на this answer.

1

Попробуйте использовать clock_gettime() с монотонной часами. http://linux.die.net/man/3/clock_gettime

Я использовал его с OpenMP, и он работал правильно.

часов() возвращает время центрального процессора, а не стены времени - смотри, например: C++: Timing in Linux (using clock()) is out of sync (due to OpenMP?)

Помните, что OpenMP обеспечивает его собственные функции для измерения времени, которые следует использовать в параллельном коде (например, omp_get_wtime()) (это не ваше дело, но на будущее :)).

Смежные вопросы