For my project I must use inline assembly instructions such as rdtsc to calculate the execution time of some C/C++ instructions.
The following code seems to work on Intel but not on ARM processors:
{unsigned a, d;asm volatile("rdtsc" : "=a" (a), "=d" (d)); t0 = ((unsigned long)a) | (((unsigned long)d) << 32);}
//The C++ statement to measure its execution time
{unsigned a, d;asm volatile("rdtsc" : "=a" (a), "=d" (d)); t1 = ((unsigned long)a) | (((unsigned long)d) << 32);}
time = t1-t0;
My question is:
How to write an inline assembly code similar to the above (to calculate the execution elapsed time of an instruction) to work on ARM processors?
You should read the PMCCNTR
register of a co-processor p15
(not an actual co-processor, just an entry point for CPU functions) to obtain a cycle count. Note that it is available to an unprivileged app only if:
Unprivileged PMCCNTR
reads are alowed:
Bit 0 of PMUSERENR
register must be set to 1 (official docs)
PMCCNTR
is actually counting cycles:
Bit 31 of PMCNTENSET
register must be set to 1 (official docs)
This is a real-world example of how it`s done.
For Arm64, the system register CNTVCT_EL0
can be used to retrieve the counter from
user space.
// SPDX-License-Identifier: GPL-2.0
u64 rdtsc(void)
{
u64 val;
/*
* According to ARM DDI 0487F.c, from Armv8.0 to Armv8.5 inclusive, the
* system counter is at least 56 bits wide; from Armv8.6, the counter
* must be 64 bits wide. So the system counter could be less than 64
* bits wide and it is attributed with the flag 'cap_user_time_short'
* is true.
*/
asm volatile("mrs %0, cntvct_el0" : "=r" (val));
return val;
}
Please refer this patch https://lore.kernel.org/patchwork/patch/1305380/ for more details.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With