esp_timer_get_time() function performance

mad_b747
Posts: 12
Joined: Sun Apr 12, 2020 1:26 pm

esp_timer_get_time() function performance

Postby mad_b747 » Sun Jun 21, 2020 3:37 pm

Hello.

Consider having a task pinned to core 1, running with no interrupts.

Inside of it, a routine is called, basically as the example below:

Code: Select all

...
unsigned long IRAM_ATTR myLoop(int64_t us)
{
	register unsigned long count = 0L;
	int64_t m = esp_timer_get_time() + us;
	while (esp_timer_get_time() < m)
	{
		count++;
	}
	return count;
}
...
After the loop, the count returned, divided by the timeout passed, gives me a performance of the loop of about ~1.35 counts per micro second.

Question: the ESP32 is running at 240 MHz, the sole uninterrupted task in core 1 should be running at 240 MHz; Why am I getting a loop performance near to 1 MHz ? does esp_timer_get_time() takes many tenths to hundredths of cycles to execute?
I was expecting the count variable to be incremented many many times faster than that.

Am I missing something here? I was hoping to have, say, 20 counts per microsecond. Or something far from "1.35"...

In time:
I tested a modification of the above loop, where I did:

Code: Select all

	while (esp_timer_get_time() < m)
	{
		count++;
		asm(" nop");
		asm(" nop");
		asm(" nop");
		asm(" nop");
		asm(" nop");
		asm(" nop");
		asm(" nop");
		asm(" nop");
		asm(" nop");
		asm(" nop");
	}
And it gives me ~1.267 counts per uS. So I think there is a HUGE overhead in the esp_timer_get_time() function.
Can this be improved? Is the esp_timer_get_time code being run from flash or something like it?

Thanks

ESP_Sprite
Posts: 9020
Joined: Thu Nov 26, 2015 4:08 am

Re: esp_timer_get_time() function performance

Postby ESP_Sprite » Sun Jun 21, 2020 7:49 pm

Sorry, it's no simple return of a variable, as that would mean having an interrupt increasing that variable once per microsecond, which would impact performance lots more... what esp_timer_get_time does instead is read some hardware timer (it actually has multiple implementations, depending which hw you want to use) and then 1. do some deeper magic to read a 64-bit variable on a 32-bit processor without the timer incrementing between the two reads, and 2. doing some math to convert it to microseconds. I can imagine this takes a few cycles.

mad_b747
Posts: 12
Joined: Sun Apr 12, 2020 1:26 pm

Re: esp_timer_get_time() function performance

Postby mad_b747 » Mon Jun 22, 2020 4:40 am

Hello.
I searched and found this function that returns the value of a clock counter register; it's just 32 bits so it overflows each ~17.9 seconds, however is fast to give a more precise delay.
Tested making a call and saving values before and after 100 asm(" nop"); statements. It returned a difference in count of 112 since before and after the nop's. So it can be usable for a finer grain count.
"xthal_get_ccount()";
- And also served to confirm that a 'nop' asm operation takes 1/240M seconds to execute - a 4.16667 ns delay

ESP_Sprite
Posts: 9020
Joined: Thu Nov 26, 2015 4:08 am

Re: esp_timer_get_time() function performance

Postby ESP_Sprite » Mon Jun 22, 2020 8:08 am

Do note that aside from only being 32-bit, the xthal_get_ccount function counts clock ticks and as such is dependent on the CPU clock frequency. If you enable dynamic clock scaling, the CPU frequency (and as such the speed of that counter) may change.

Who is online

Users browsing this forum: Baidu [Spider], Bing [Bot], Majestic-12 [Bot] and 120 guests