2010-04-29 7 views
10

Come è possibile dimostrare agli studenti l'usabilità dei suggerimenti del compilatore likely e unlikely (__builtin_expect)?Esempio di apprendimento di suggerimenti del probabile() e improbabile()

È possibile scrivere un codice di esempio, che sarà più volte più veloce con questi suggerimenti che confrontano il codice senza suggerimenti.

+2

http://kerneltrap.org/node/4705 –

+0

@ T.J. Crowder, sì. ma voglio un esempio di programma in cui gli studenti possano SENTIRE la differenza, non leggerlo in assembler. – osgx

+1

@osgx: non otterrai un campione del genere, perché non c'è alcuna differenza da sentire. Questo è il peggior, il più brutto tipo di micro-ottimizzazione inutile. –

risposta

22

Ecco quello che uso, un'implementazione molto inefficiente dei numeri di Fibonacci:

#include <stdio.h> 
#include <inttypes.h> 
#include <time.h> 
#include <assert.h> 

#define likely(x) __builtin_expect((x),1) 
#define unlikely(x) __builtin_expect((x),0) 

uint64_t fib(uint64_t n) 
{ 
    if (opt(n == 0 || n == 1)) { 
     return n; 
    } else { 
     return fib(n - 2) + fib(n - 1); 
    } 
} 

int main(int argc, char **argv) 
{ 
    int i, max = 45; 
    clock_t tm; 

    if (argc == 2) { 
     max = atoi(argv[1]); 
     assert(max > 0); 
    } else { 
     assert(argc == 1); 
    } 

    tm = -clock(); 
    for (i = 0; i <= max; ++i) 
     printf("fib(%d) = %" PRIu64 "\n", i, fib(i)); 
    tm += clock(); 

    printf("Time elapsed: %.3fs\n", (double)tm/CLOCKS_PER_SEC); 
    return 0; 
} 

di dimostrare, utilizzando GCC:

~% gcc -O2 -Dopt= -o test-nrm test.c 
~% ./test-nrm 
... 
fib(45) = 1134903170 
Time elapsed: 34.290s 

~% gcc -O2 -Dopt=unlikely -o test-opt test.c 
~% ./test-opt 
... 
fib(45) = 1134903170 
Time elapsed: 33.530s 

A poche centinaia di millisecondi meno. Questo guadagno è dovuto alla previsione del ramo aiutato dal programmatore.

Ma ora, per quello che il programmatore in realtà dovrebbe essere fare invece:

~% gcc -O2 -Dopt= -fprofile-generate -o test.prof test.c 
~% ./test.prof 
... 
fib(45) = 1134903170 
Time elapsed: 77.530s /this run is slowed down by profile generation. 

~% gcc -O2 -Dopt= -fprofile-use -o test.good test.c 
~% ./test.good 
fib(45) = 1134903170 
Time elapsed: 17.760s 

Con compilatore-aided profiling runtime, siamo riusciti a ridurre le 34.290s originali alla 17.760s. Molto meglio che con la previsione di branch assistito dal programmatore!

+1

, ma è necessario dimostrare "probabile" e "improbabile" – osgx

+19

aah, tm = -clock(); tm + = clock(); è bellissimo, non l'ho visto prima, grazie! –

+0

Penso che ciò dimostri che 'probabile' e' improbabile' non sono molto utili. Forse anche questa è una pessima implementazione di 'fib()' ... –

Problemi correlati