I3MPS_Opgave10

=Programmet, timing og cache miss.= Til denne øvelse laver vi 2 programmer, som skal gange 2 matrix sammen. Forskellen på disse programmer, er det første program gør direkte brug af dataen, mens det andet program ligger det ene matrix i cachen inden brug. Programmerne ser således ud:

matrix_mul_slow.c code format="cpp" int main {   int N = 500; double res[N][N], mul1[N][N], mul2[N][N];

for(int i = 0; i < N; ++i) {       for(int j = 0; j < N; ++j) {           for(int k = 0; k < N; ++k) res[i][j] += mul1[i][k] * mul2[k][j]; }   }

return res[N][N]; } code

matrix_mul_fast.c code format="cpp" int main {   int N = 500; double res[N][N], mul1[N][N], mul2[N][N], tmp[N][N];

for(int i = 0; i < N; ++i) {       for(int j = 0; j < N; ++j) {           tmp[i][j] = mul2[j][i]; }   }

for(int i = 0; i < N; ++i) {       for(int j = 0; j < N; ++j) {           for(int k = 0; k < N; ++k) res[i][j] += mul1[i][k] * tmp[j][k]; }   }

return res[N][N]; } code

Disse programmer kompileres og kaldes hendholdsvis "slow" og "fast". Det er nu muligt at time hvor hurtigt de forskellige programmer afvikles.

code martin@martin-VirtualBox:~/Dropbox/Linux/MPS/Exc10$ time ./slow

real   0m1.736s user   0m1.092s sys    0m0.008s martin@martin-VirtualBox:~/Dropbox/Linux/MPS/Exc10$ time ./fast

real   0m0.968s user   0m0.888s sys    0m0.028s

code Det kan ses selv om "fast" programmet bruger tid på at ligge det ene matrix i cache, og bruger mere memory, er det stadig hurtigere end "slow".

Nu kan vi køre cachegrind, for at se hvor mange cache misses der er

code

3865
I  refs:      6,003,349,395

3865
I1 misses:              686

3865
LLi misses:             683

3865
I1 miss rate:          0.00%

3865
LLi miss rate:         0.00%

3865
D  refs:      2,376,538,165  (2,251,277,416 rd   + 125,260,749 wr)

3865
D1 misses:      113,163,153  (  113,162,680 rd   +         473 wr)

3865
LLd misses:          95,208  (       94,779 rd   +         429 wr)

3865
D1 miss rate:           4.7% (          5.0%     +         0.0%  )

3865
LLd miss rate:          0.0% (          0.0%     +         0.0%  )

3865
LL refs:        113,163,839  (  113,163,366 rd   +         473 wr)

3865
LL misses:           95,891  (       95,462 rd   +         429 wr)

3865
LL miss rate:           0.0% (          0.0%     +         0.0%  ) code

=Optimerings Parametre og deres effekt= G++ giver os muligheder for forskellige niveauer af optimering. Her tester vi hvordan de forskellige optimeringer påvirker program størrelse, hastighed og cache miss.

Slow
 * || **-O0** || **-O1** || **-O2** || **-O3** ||
 * **Størrelse** || 9801B || 10573B || 10637B || 10645B ||
 * **Hastighed** || 0m1.264s || 0m0.507s || 0m0608s || 0m0.276s ||
 * **Cache Miss** || 4.7% || 44.6% || 44.6% || 29.1% ||

Fast
 * || **-O0** || **-O1** || **-O2** || **-O3** ||
 * **Størrelse** || 9953B || 108885B || 11101B || 11101B ||
 * **Hastighed** || 0m1.071s || 0m0.199s || 0m0.250s || 0m0.209s ||
 * **Cache Miss** || 0.6% || 6.3% || 6.3% || 6.3% ||

=Timing på DevKit= Vi kompilere fast programmet, og timer det på DevKittet. code root@beagleboard:~# time ./fast Segmentation fault

real   0m46.052s user   0m45.855s sys    0m0.117s

code Den segmentation fault vi her får, kan skyldes manglende hukommelse på DevKittet. Hvis programmet afvikles med N = 50 fremfor N = 500, får vi følgende resultat code root@beagleboard:~# time ./fast

real   0m0.068s user   0m0.047s sys    0m0.020s

code