Reputation: 187
So here is my issue. I have written a C++ matrix multiplication code in serial and in parallel. I want to calculate the time it takes each one to execute. In other words the output should look like this:
"Serial Multiplication time: #### seconds."
"Parallel Multiplication time: #### seconds."
But the problem I am running into is running this code on a linux machine. It works perfectly on windows, but I need to run this code in linux. When I run the code, he serial multiplication time gives me a value, but the parallel time give me a higher values, but it runs faster. For example, I ran a matrix multiplication with two matrices each 1000x1000. The serial time was 9 seconds, and the parallel time was 18 seconds, but it took a fraction of the time for the computation to complete. I waited for a while for the serial multiplication to finish but the parallel multiplication finished right away just with some wrong value for elapsed time. Here is my code:
#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;
}
}
}
Please help figure this out! I have no idea why it will not correctly count time in Linux. Like I said, I have no problems in windows, but I need to run this in linux, because I have bigger matrix calculations that need to run on a Linux cluster and will accurately record the time!
Thanks!!
JD
Upvotes: 0
Views: 849
Reputation: 966
The clock
function actually measures the time you spend actively on the CPU, not the wall time. It is not very useful in your case because it measures the combined CPU time of all threads and it is usually more than the wall time.
If you do not need high time resolution, you can use time
function that measures wall time, but has one second resolution. If you need more precise timing, you can take a look at this answer.
Upvotes: 4
Reputation: 141
Try using clock_gettime() with monotonic clock. http://linux.die.net/man/3/clock_gettime
I've been using it with OpenMP and it worked correctly.
clock() returns a cpu time, not wall time - see for example: C++: Timing in Linux (using clock()) is out of sync (due to OpenMP?)
Remember that OpenMP provides it's own functions for time measurement that you should use inside parallel code (like omp_get_wtime()
) (that's not your case, but for the future :)).
Upvotes: 1