【发布时间】:2015-07-29 13:21:15
【问题描述】:
我问自己什么是衡量并行程序性能(以失败计)的最佳方法。我读到了 papi_flops。这似乎适用于串行程序。但我不知道如何衡量并行程序的整体性能。
我想测量一个 blas/lapack 函数的性能,在我下面的 gemm 示例中。但我也想测量其他功能,特别是操作次数未知的功能。 (在 gemm 的情况下,ops 是已知的(ops(gemm) = 2*n^3),所以我可以将性能计算为操作数和执行时间的函数。)库(我使用的是 Intel MKL) 自动生成线程。所以不能单独衡量每个线程的性能,然后再降低。
这是我的例子:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "mkl.h"
#include "omp.h"
#include "papi.h"
int main(int argc, char *argv[] )
{
int i, j, l, k, n, m, idx, iter;
int mat, mat_min, mat_max;
int threads;
double *A, *B, *C;
double alpha =1.0, beta=0.0;
float rtime1, rtime2, ptime1, ptime2, mflops;
long long flpops;
#pragma omp parallel
{
#pragma omp master
threads = omp_get_num_threads();
}
if(argc < 4){
printf("pass me 3 arguments!\n");
return( -1 );
}
else
{
mat_min = atoi(argv[1]);
mat_max = atoi(argv[2]);
iter = atoi(argv[3]);
}
m = mat_max; n = mat_max; k = mat_max;
printf (" Initializing data for matrix multiplication C=A*B for matrix \n"
" A(%ix%i) and matrix B(%ix%i)\n\n", m, k, k, n);
A = (double *) malloc( m*k * sizeof(double) );
B = (double *) malloc( k*n * sizeof(double) );
C = (double *) malloc( m*n * sizeof(double) );
printf (" Intializing matrix data \n\n");
for (i = 0; i < (m*k); i++)
A[i] = (double)(i+1);
for (i = 0; i < (k*n); i++)
B[i] = (double)(-i-1);
memset(C,0,m*n*sizeof(double));
// actual meassurment
for(mat=mat_min;mat<=mat_max;mat+=5)
{
m = mat; n = mat; k = mat;
for( idx=-1; idx<iter; idx++ ){
PAPI_flops( &rtime1, &ptime1, &flpops, &mflops );
cblas_dgemm(CblasColMajor, CblasNoTrans, CblasNoTrans,
m, n, k, alpha, A, k, B, n, beta, C, n);
PAPI_flops( &rtime2, &ptime2, &flpops, &mflops );
}
printf("%d threads: %d in %f sec, %f MFLOPS\n",threads,mat,rtime2-rtime1,mflops);fflush(stdout);
}
printf("Done\n");fflush(stdout);
free(A);
free(B);
free(C);
return 0;
}
这是一个输出(矩阵大小为 200):
1 threads: 200 in 0.001459 sec, 5570.258789 MFLOPS
2 threads: 200 in 0.000785 sec, 5254.993652 MFLOPS
4 threads: 200 in 0.000423 sec, 4919.640137 MFLOPS
8 threads: 200 in 0.000264 sec, 3894.036865 MFLOPS
我们可以看到函数 gemm 的执行时间是可伸缩的。但我测量的失败只是线程 0 的性能。
我的问题是:如何衡量整体表现?我很感激任何意见。
【问题讨论】:
-
嗯.. 测量每个线程的 flops,然后将它们加在一起?
-
我该怎么做? blas 库创建线程。因此,并行区域位于函数调用 dgemm 内部。我无权访问各个线程。当然,我可以重新编译 blas 库,然后在并行区域内测量每个线程的性能(在 MKL 的情况下不可能,好吧我可以切换到 OpenBlas)。但这是我想要避免的。
-
你能显示失败的次数吗?也许 mflops 是所有线程的平均值?
标签: c multithreading performance blas papi