我正在Visual Studio(实际上是C ++)中编写代码,并且我意识到在并行运行特定功能(仅进行基本矩阵乘法)时,在相同条件下进行不同运行所花费的计算时间会大大不同。 / p>
具有以下令人困惑的输出: 1 /第一次运行并行化函数时,omg_get_wtime()提供了比串行版本高的计算时间 2 /随后的时间,我称之为计算时间。 我的问题是:同一个函数为什么会在第一时间给出不同的时间(即,第一次运行与随后的运行给出的时间完全不同...)
#include<iostream>
#include<conio.h>
#include<iomanip>
#include<omp.h>
#include<stdlib.h>
using namespace std;
const int ROW = 50;
const int COL = 50;
class matmul
{
int a[ROW][COL];
int row;
int col;
//int* prow;
public:
matmul() : row(0), col(0) {}
~matmul() {}
void display();
matmul multiply_par1(matmul m1, matmul m2);
void generate_matrix(int row, int col);
};
void matmul::display()
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
cout << setw(5) << a[i][j];
cout << endl;
}
}
matmul matmul::multiply_par1(matmul m1, matmul m2)
{
int i = 0;
int j = 0;
int k = 0;
matmul temp;
temp.row = m1.row;
temp.col = m2.col;
double st = omp_get_wtime();
int nbr = m1.row;
int nbc = m2.col;
#pragma omp parallel private( i, j, k) // shared(nbr,nbc)
for (i = 0; i < nbr; i++)
for (j = 0; j < nbc; j++)
{
temp.a[i][j] = 0;
{
for (k = 0; k < temp.col; k++)
temp.a[i][j] += m1.a[i][k] * m2.a[k][j];
}
}
double en = omp_get_wtime();
printf("Parallel run: %lf\n", en - st);
return temp;
}
void matmul::generate_matrix(int r, int c)
{
//matrix temp;
row = r;
col = c;
for (int i = 0; i < row; i++)
for (int j = 0; j < col; j++)
{
a[i][j] = rand() % 10;
}
}
int main()
{
int Size = 10;
int* arr = new int[Size];
matmul m1, m2, m3, m4, m5,m6,m7;
int r1, c1;
if (Size > 100)
{
cout << "matrix quite large to display...\n";
}
else
{
cout << "Generating 1rst matrix...\n";
m1.generate_matrix(10, 10);
m1.display();
cout << "Generating 2nd matrix...\n";
m2.generate_matrix(10, 10);
m2.display();
m4 = m3.multiply_par1(m1, m2);
cout << "Resultant parallel matrix is :\n";
//m5.display();
m5 = m3.multiply_par1(m1, m2);
cout << "Resultant parallel matrix is :\n";
//m6.display();
m6 = m3.multiply_par1(m1, m2);
cout << "Resultant parallel matrix is :\n";
//m6.display();
m7 = m3.multiply_par1(m1, m2);
cout << "Resultant parallel matrix is :\n";
//m6.display();
}
return 0;
}
我希望运行时间完全相同,但是第一个是明显不同的。执行时得到以下输出:
Parallel running time: 0.000583
Resultant parallel matrix is :
Parallel running time: 0.000016
Resultant parallel matrix is :
Parallel running time: 0.000014
Resultant parallel matrix is :
Parallel running time: 0.000014
Resultant parallel matrix is :
您看到的0.000583确实不合适,我也不明白为什么...
至关重要的是,在上面的代码仅使用一次的情况下(例如500x500矩阵),我们是否可以对代码进行改进以产生更好的wtime()?
答案 0 :(得分:4)
OpenMP必须在执行并行节(details)之前创建线程。创建线程需要时间,这是您在第一次测量中所观察到的。
但是,OpenMP实现不会在并行区域之间创建新的线程,因为它使用线程池(回收先前创建的线程)。这就是为什么后续测量要好得多的原因。
在您的情况下,矩阵很小,因此线程创建的开销掩盖了多线程的优点。但是,对于后续调用,使用多线程可能仍然是有益的。因此,请始终测量第一个,第二个和总平均值,以确保从长远来看值得并行执行代码。