मैंने अपने आप से पूछा कि समांतर कार्यक्रम के प्रदर्शन (फ्लॉप में) को मापने का सबसे अच्छा तरीका क्या होगा। मैंने papi_flops के बारे में पढ़ा। ऐसा लगता है कि एक धारावाहिक कार्यक्रम के लिए ठीक काम करता है। लेकिन मुझे नहीं पता कि मैं समानांतर कार्यक्रम के समग्र प्रदर्शन को कैसे माप सकता हूं।समांतर कार्यक्रमों (पापी के साथ)
मैं नीचे दिए गए उदाहरण में अपने उदाहरण में ब्लैस/लैपैक फ़ंक्शन के प्रदर्शन को मापना चाहता हूं। लेकिन मैं अन्य कार्यों को भी मापना चाहता हूं, विशेष रूप से कार्य जहां ऑपरेशन की संख्या ज्ञात नहीं है। (जीएमएम के मामले में ओप्स ज्ञात हैं (ओप (जीएमएम) = 2 * एन^3), इसलिए मैं संचालन की संख्या और निष्पादन समय के कार्य के रूप में प्रदर्शन की गणना कर सकता हूं।) लाइब्रेरी (मैं इंटेल का उपयोग कर रहा हूं एमकेएल) धागे स्वचालित रूप से spawn। तो मैं व्यक्तिगत रूप से प्रत्येक धागे के प्रदर्शन को माप नहीं सकता और फिर इसे कम कर सकता हूं।
#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 का प्रदर्शन है।
मेरा प्रश्न है: मैं समग्र प्रदर्शन को कैसे माप सकता हूं? मैं किसी भी इनपुट के लिए आभारी हूँ।
उम्म .. प्रत्येक धागे के लिए फ्लॉप मापें और फिर उन्हें एक साथ जोड़ें? – Voo
मैं यह कैसे कर सकता हूं? ब्लैस लाइब्रेरी धागे बनाते हैं। तो, समांतर क्षेत्र फ़ंक्शन कॉल dgemm के अंदर है। मेरे पास व्यक्तिगत धागे तक पहुंच नहीं है। बेशक मैं ब्लैस लाइब्रेरी को फिर से कंपाइल कर सकता हूं और फिर समांतर क्षेत्र के अंदर प्रत्येक थ्रेड के लिए प्रदर्शन को मापता हूं (एमकेएल के मामले में संभव नहीं है, ठीक है, मैं ओपनब्लैस पर स्विच कर सकता हूं)। लेकिन यही वह है जिसे मैं टालना चाहता हूं। – Sebastian
क्या आप फ्लॉप की संख्या दिखा सकते हैं? शायद mflops सभी धागे में औसत है? –