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);

questionAnswers(2)

yourAnswerToTheQuestion