2012-03-20 13 views
7

Utilizzo un processore Exynos 3110 (1-core ARM Cortex-A8 da 1 GHz, ad esempio utilizzato nel Nexus S) e provo a misurare i tempi di esecuzione di particolari funzioni. Ho un Android 4.0.3 in esecuzione sul Nexus S. I provato il metodo daMisurare il tempo di esecuzione su ARM Cortex-A8 utilizzando il contatore hardware

[1] How to measure program execution time in ARM Cortex-A8 processor?

ho caricato il modulo del kernel per permettere la lettura dei valori di registro in modalità utente. Sto usando il seguente programma per testare il contatore:

static inline unsigned int get_cyclecount (void) 
{ 
    unsigned int value; 
    // Read CCNT Register 
    asm volatile ("MRC p15, 0, %0, c9, c13, 0\t\n": "=r"(value)); 
    return value; 
} 


static inline void init_perfcounters (int do_reset, int enable_divider) 
{ 
    // in general enable all counters (including cycle counter) 
    int value = 1; 

    // peform reset: 
    if (do_reset) 
    { 
     value |= 2;  // reset all counters to zero. 
     value |= 4;  // reset cycle counter to zero. 
    } 

    if (enable_divider) 
     value |= 8;  // enable "by 64" divider for CCNT. 

    value |= 16; 

    // program the performance-counter control-register: 
    asm volatile ("MCR p15, 0, %0, c9, c12, 0\t\n" :: "r"(value)); 

    // enable all counters: 
    asm volatile ("MCR p15, 0, %0, c9, c12, 1\t\n" :: "r"(0x8000000f)); 

    // clear overflows: 
    asm volatile ("MCR p15, 0, %0, c9, c12, 3\t\n" :: "r"(0x8000000f)); 
} 


int main(int argc, char **argv) 
{ 
    int i = 0; 
    unsigned int start = 0; 
    unsigned int end = 0; 

    printf("Hello Counter\n"); 

    init_perfcounters(1,0); 

    for(i=0;i<10;i++) 
    { 
     start = get_cyclecount(); 
     sleep(1); // sleep one second 
     end = get_cyclecount(); 

     printf("%u %u %u\n", start, end, end - start); 
    } 

    return 0; 
} 

Secondo [1] il contatore viene incrementato ad ogni ciclo di clock. Ho cambiato lo scaling_governor in userspace e impostato la frequenza della CPU a 1GHz per assicurarmi che la frequenza di clock non cambi da Android.

Se si esegue il programma, vengono eseguiti i periodi di sospensione di 1 secondo, ma i valori del contatore sono compresi nell'intervallo ~ 200e6, anziché 1e9 previsto. C'è qualcosa di specifico del processore che mi manca qui? La velocità di clock dei contatori è diversa dalla frequenza di clock del processore?

+1

Cool .. Il codice che hai postato è * esattamente * il codice che ho scritto due anni fa .. Mi chiedo solo: da dove lo hai preso? –

+2

Ciao Nils, è il tuo codice e ho citato l'argomento da quel momento ;-) Hai idea del motivo per cui ottengo il fattore 5 nei valori del timer? Grazie – user1207228

+1

Il tempo misurato cambia se fai un lavoro vero per un secondo invece di dormire? –

risposta

1

Controlla la pagina di questo professore: http://users.ece.utexas.edu/~valvano/arm/ Ha più programmi di esempio completi che hanno a che fare con tempo/periodico-timer/misurazione-esecuzione-tempo, sono sviluppati per microcontrollori basati su ARM Cortex-M3. Spero che questo non sia molto diverso da quello su cui stai lavorando. Performance Performance.c

0

Sei sicuro che i governatori siano utilizzati in Android per la gestione delle prestazioni nello stesso modo in Linux standard? E stai usando un'immagine Android personalizzata o una fornita dal produttore? Assumerei che ci siano politiche di livello inferiore in vigore nell'immagine fornita dal produttore (legata al sonno o all'attività del modem, ecc.). Potrebbe anche essere che il codice di sospensione scala direttamente la tensione e la frequenza. Potrebbe essere utile disabilitare l'intero CPUFreq non solo le politiche (oi governatori).