Skip to content

Instantly share code, notes, and snippets.

@jef-sure
Last active December 29, 2022 09:54
Show Gist options
  • Save jef-sure/208bbd829e8b909cfb10ac8bd743b01d to your computer and use it in GitHub Desktop.
Save jef-sure/208bbd829e8b909cfb10ac8bd743b01d to your computer and use it in GitHub Desktop.
ESP32 Indirect function call performance test
#include <stdint.h>
#include <stdio.h>
#include <stdbool.h>
#include <unistd.h>
#include <limits.h>
#include "esp_timer.h"
#include "esp_task_wdt.h"
#define TEST_COUNT 10000000
int fn_1(int a) {
return a * 8;
}
int fn_4(int a) {
return a * 2;
}
int fn_8(int a) {
return a;
}
int fn_12(int a) {
return (a >> 1) + (a >> 3) + (a >> 5) + (a >> 7) + (a >> 9) + (a >> 11) + (a >> 13) + (a >> 15) + (a >> 17);
}
int fn_16(int a) {
return a >> 1;
}
int direct_if(int fn) {
int i, b = 0;
if (fn == 1) {
for (i = 0; i < TEST_COUNT; ++i)
b = fn_1(b + i);
} else if (fn == 4) {
for (i = 0; i < TEST_COUNT; ++i)
b = fn_4(b + i);
} else if (fn == 8) {
for (i = 0; i < TEST_COUNT; ++i)
b = fn_8(b + i);
} else if (fn == 12) {
for (i = 0; i < TEST_COUNT; ++i)
b = fn_12(b + i);
} else if (fn == 16) {
for (i = 0; i < TEST_COUNT; ++i)
b = fn_16(b + i);
}
return b;
}
int direct_switch(int fn) {
int i, b = 0;
switch (fn) {
case 1:
for (i = 0; i < TEST_COUNT; ++i)
b = fn_1(b + i);
break;
case 4:
for (i = 0; i < TEST_COUNT; ++i)
b = fn_4(b + i);
break;
case 8:
for (i = 0; i < TEST_COUNT; ++i)
b = fn_8(b + i);
break;
case 12:
for (i = 0; i < TEST_COUNT; ++i)
b = fn_12(b + i);
break;
case 16:
for (i = 0; i < TEST_COUNT; ++i)
b = fn_16(b + i);
}
return b;
}
typedef int (*fn_t)(int);
enum {
TestedFBits = 5
};
fn_t FPointers[TestedFBits] = { fn_1, fn_4, fn_8, fn_12, fn_16 };
int FIndexes[TestedFBits] = { 1, 4, 8, 12, 16 };
int indirect_version(fn_t fn) {
int i, b = 0;
for (i = 0; i < TEST_COUNT; ++i) {
b = fn(b + i);
}
return b;
}
int GlobalVar;
void app_main(void) {
int64_t start_clock, end_clock;
start_clock = esp_timer_get_time();
for (int8_t i = 0; i < TestedFBits; i++) {
int bits = FIndexes[i];
GlobalVar += direct_if(bits);
}
end_clock = esp_timer_get_time();
printf("direct_if took: %lld micros\n", end_clock - start_clock);
start_clock = esp_timer_get_time();
for (int8_t i = 0; i < TestedFBits; i++) {
int bits = FIndexes[i];
GlobalVar += direct_switch(bits);
}
end_clock = esp_timer_get_time();
printf("direct_switch took: %lld micros\n", end_clock - start_clock);
start_clock = esp_timer_get_time();
for (int8_t i = 0; i < TestedFBits; i++) {
GlobalVar += indirect_version(FPointers[i]);
}
end_clock = esp_timer_get_time();
printf("indirect_version took: %lld micros\n", end_clock - start_clock);
while (1) {
GlobalVar++;
}
}
__DATA__
gcc 11.2
-O2:
direct_if took: 1254457 micros
direct_switch took: 1672600 micros
indirect_version took: 4390699 micros
-Os:
direct_if took: 1965483 micros
direct_switch took: 2132584 micros
indirect_version took: 4599714 micros
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment