Liczniki wydajności ARM vs linux clock_gettime

Używam chipu Zynq na płycie programistycznej (ZC702), która ma podwójny cortex-A9 MPCore o częstotliwości 667 MHz i ma jądro Linux 3.3 Chciałem porównać czas wykonania programu, więc najpierw użyłem clock_gettime, a następnie użyłem liczniki dostarczone przez koprocesora ARM. Licznik zwiększa się co jeden cykl procesora. ( oparte na tympytanie o stackoverflow ito)

Kompiluję program z flagą -O0 (ponieważ nie chcę żadnej zmiany kolejności ani optymalizacji)

Czas I mierzony licznikami wydajności wynosi 583833498 (cykle) / 666,666687 MHz =875750.221 (mikrosekundy)

Podczas używania clock_gettime () (REALTIME lub MONOTONIC lub MONOTONIC_RAW) zmierzony czas to:731627.126 (mikrosekund)150000 mikrosekund mniej ..

Czy ktoś może mi wyjaśnić, dlaczego tak się dzieje? Dlaczego jest różnica? Procesor nie działa w skali zegara, jak można uzyskać mniejszy czas wykonania mierzony przez clock_gettime? Mam przykładowy kod poniżej:

#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