Contadores de desempenho do ARM vs linux clock_gettime
Eu estou usando um chip Zynq em uma placa de desenvolvimento (ZC702), que tem um MPCore dual cortex-A9 a 667MHz e vem com um kernel Linux 3.3 Eu queria comparar o tempo de execução de um programa, então usei o clock_gettime e usei o contadores fornecidos pelo coprocessador de ARM. O contador incrementa todo ciclo de um processador. ( com base nissopergunta de stackoverflow eisto)
Eu compilar o programa com o sinalizador -O0 (desde que eu não quero qualquer reordenação ou otimização feita)
O tempo que meço com os contadores de desempenho é 583833498 (ciclos) / 666.666687 MHz =875750.221 (microssegundos)
Ao usar clock_gettime () (REALTIME ou MONOTONIC ou MONOTONIC_RAW), o tempo medido é:731627.126 (microssegundos) que é150000 microssegundos menos ..
Alguém pode me explicar por que isso está acontecendo? Por que existe uma diferença? O processador não escala o relógio, como é possível obter menos tempo de execução medido pelo clock_gettime? Eu tenho um código de exemplo abaixo:
#define RUNS 50000000
#define BENCHMARK(val) \
__asm__ __volatile__("mov r4, %1\n\t" \
"mov r5, #0\n\t" \
"1:\n\t"\
"add r5,r5,r4\n\t"\
"mov r4 ,r4 \n\t" \
"mov r4 ,r4 \n\t" \
"mov r4 ,r4 \n\t" \
"mov r4 ,r4 \n\t" \
"mov r4 ,r4 \n\t" \
"mov r4 ,r4 \n\t" \
"mov r4 ,r4 \n\t" \
"mov r4 ,r4 \n\t" \
"mov r4 ,r4 \n\t" \
"mov r4 ,r4 \n\t" \
"sub r4,r4,#1\n\t" \
"cmp r4, #0\n\t" \
"bne 1b\n\t" \
"mov %0 ,r5 \n\t" \
:"=r" (val) \
: "r" (RUNS) \
: "r4","r5" \
);
clock_gettime(CLOCK_MONOTONIC_RAW,&start);
__asm__ __volatile__ ("MRC p15, 0, %0, c9, c13, 0\t\n": "=r"(start_cycles));
for(index=0;index<5;index++)
{
BENCHMARK(i);
}
__asm__ __volatile__ ("MRC p15, 0, %0, c9, c13, 0\t\n": "=r"(end_cycles));
clock_gettime(CLOCK_MONOTONIC_RAW,&stop);