All,
When I am using the cycle counter in AArch64, I am not getting cycles properly. I have enabled read of pmccntr_el0 in user space using a small kernel module. I have sample code like:
asm volatile("isb;mrs %0, pmccntr_el0" : "=r"(prev)); sleep(1); asm volatile("isb;mrs %0, pmccntr_el0" : "=r"(curr)); delta = curr-prev;
I expected delta to be in the range of 1400000000 as a57 in our design runs at 1400MHz
But I am getting around 32100000 which means the cycle counter frequency is ~3.21MHz
The value of Control register is pmcr=41013001 indicating divider is off.
With Generic timer counter registers, I am getting the values as expected. The below code gives
asm volatile ("isb; mrs %0, cntvct_el0" : "=r" (ts)); sleep (2); asm volatile ("isb; mrs %0, cntvct_el0" : "=r" (te)); asm volatile ("isb; mrs %0, cntfrq_el0" : "=r" (freq)); printf ("Aarch64 %20ld cycles\n", (unsigned long long)(te - ts)); printf (" Frequency = %u\n",freq);
I get count of 512021629 cycles for 2 sec as expected for 256MHz frequency which I got from cntfrq_el0.
cntfrq_el0.
Is there something basic I am missing for PMCCNTR_EL0?
PMCCNTR_EL0?
thanks and regards,
Ravi
With the caveat that I'm not a Linux expert, my suspicion is power management. The Generic Timer measures time, but the PMU is counting cycles. If your system has a light load, it might well be either reducing the clock frequency or taking the core off-line entirely. Both of which would reduce the number of cycles experienced by the core, but not the passage of time.
My guess would be taking the core off-line, but it is only a guess.
Just to add fuel to the fire: the cycle counter counts CLK cycles consumed by the processor - when in WFI or WFE state, the PMU won't count, so it may not even be 'offline' or have a reduced input clock rate.
When you sleep(1) you're telling the kernel that you want to wait a second, which is an ideal time for the kernel to set up a timer 1 second in the future and then, in the absence of anything else to do, might end up in the idle loop (WFI..) fairly quickly.
Ta,
Matt
Matt,
Thanks. I will try with some normal code which does not include sleep. However, I am looking for a counter similar to rdtsc (Read Timestamp) in X86 which gives me ticks since the system started with nanosecond granularity to do some time measurements. If WFI/WFE stops PMU cycle counter that will not help. Is there any other counter I can use?
regards,
I was thinking of deeper sleep modes that standby, but...
It depends on what you actually want to know. If what you know is the elapsed time, then you can use the Generic Timer. It
I guess in ARM-7 architecture (in A15) this was not the case. The CCNT was counting all the cycles (or divided by 64). Using generic timer is not that accurate. For example, in our design the frequency of timer is 256Mhz and CPU frequency is 1600MHz. So, the counter will be 8 times slower.
In case of X86, the rdtsc keeps incrementing at a constant rate irrespective if CPU frequency scaling etc so that we can depend on that to timestamp measurements.
View all questions in Cortex-A / A-Profile forum