Skip to content

Instantly share code, notes, and snippets.

@HiperDoo
Created April 14, 2023 21:39
Show Gist options
  • Save HiperDoo/c876247d102b66d27c4d3add003a73cd to your computer and use it in GitHub Desktop.
Save HiperDoo/c876247d102b66d27c4d3add003a73cd to your computer and use it in GitHub Desktop.
#ifndef BENCHMARKS_HPP
#define BENCHMARKS_HPP
#include <Arduino.h>
struct Time_Results {
uint32_t digital;
uint32_t gpio_;
uint32_t GPIO;
uint32_t REG;
};
extern void benchmark_read_gpio(Time_Results& results) {
const uint32_t BM_ITERATIONS = 10000000;
const uint32_t pin = GPIO_NUM_16;
unsigned long clock;
bool value;
// digitalRead()
clock = millis();
for(uint32_t i = 0; i < BM_ITERATIONS; i++)
value = digitalRead(pin);
results.digital = millis() - clock;
// gpio_get_level()
clock = millis();
for(uint32_t i = 0; i < BM_ITERATIONS; i++)
value = gpio_get_level((gpio_num_t)pin);
results.gpio_ = millis() - clock;
// GPIO.in
clock = millis();
for(uint32_t i = 0; i < BM_ITERATIONS; i++)
value = (GPIO.in >> pin) & 0x1;
results.GPIO = millis() - clock;
// REG_READ()
clock = millis();
for(uint32_t i = 0; i < BM_ITERATIONS; i++)
value = REG_READ(GPIO_IN_REG) & pin;
results.REG = millis() - clock;
}
extern void benchmark_write_gpio(Time_Results& results) {
const uint32_t BM_ITERATIONS = 10000000;
const uint32_t pin = GPIO_NUM_17;
unsigned long clock;
// digitalWrite()
clock = millis();
for(size_t i = 0; i < BM_ITERATIONS; i++) {
digitalWrite(pin, HIGH);
digitalWrite(pin, LOW);
}
results.digital = millis() - clock;
// gpio_get_level()
clock = millis();
for(uint32_t i = 0; i < BM_ITERATIONS; i++) {
gpio_set_level((gpio_num_t)pin, HIGH);
gpio_set_level((gpio_num_t)pin, LOW);
}
results.gpio_ = millis() - clock;
// GPIO.in
clock = millis();
for(uint32_t i = 0; i < BM_ITERATIONS; i++) {
GPIO.out_w1ts = (uint32_t)1 << pin;
GPIO.out_w1tc = (uint32_t)1 << pin;
}
results.GPIO = millis() - clock;
// REG_WRITE()
clock = millis();
for(uint32_t i = 0; i < BM_ITERATIONS; i++) {
REG_WRITE(GPIO_OUT_W1TS_REG, (uint32_t)1 << pin);
REG_WRITE(GPIO_OUT_W1TC_REG, (uint32_t)1 << pin);
}
results.REG = millis() - clock;
}
extern int benchmark_primes(const int num) {
int foundPrime{0};
for (int i = 2; i < num; ++i) {
int flag_var = 0;
for (int j = 2; j <= i / 2; ++j) {
if (i % j == 0) {
flag_var = 1;
break;
}
}
if (flag_var == 0) {
foundPrime++;
}
}
return foundPrime;
}
extern double benchmark_pi(const int n) {
double sum{0.0f}, term, pi;
for (int i = 0; i < n; i++) {
term = pow(-1, i) / (2 * i + 1);
sum += term;
}
pi = 4 * sum;
return pi;
}
#endif
#include "Benchmarks.hpp"
#include "soc/rtc_wdt.h"
#include "freertos/semphr.h"
TaskHandle_t task;
Time_Results Time_1, Time_2;
//xSemaphoreHandle atomic_print{0};
#define TOGGLE 0
void loop2(void*);
void setup() {
Serial.begin(115200);
pinMode(16, INPUT);
pinMode(17, OUTPUT);
rtc_wdt_protect_off();
rtc_wdt_disable();
disableCore0WDT();
disableLoopWDT();
//atomic_print = xSemaphoreCreateMutex();
Serial.printf(PSTR("===== BENCHMARKS =====\n"));
delay(500);
xTaskCreatePinnedToCore(
loop2,
"loop2",
10000,
NULL,
1,
&task,
0
);
}
void loop() {
while (1) {
#if TOGGLE
benchmark_read_gpio(Time_1);
Serial.printf(PSTR(
">>> BENCHMARK READ <<< Core: %d\n"
" * digitalWrite(): %lu ms\n"
" * gpio_get_level(): %lu ms\n"
" * GPIO.in: %lu ms\n"
" * REG_READ(): %lu ms\n\n"
), xPortGetCoreID(), Time_1.digital, Time_1.gpio_, Time_1.GPIO, Time_1.REG);
#else
uint32_t clock = millis();
int result = benchmark_primes(300000);
clock = millis() - clock;
Serial.printf(PSTR(
">>> BENCHMARK PRIME <<< Core: %d\n"
" * Prime: %d\n"
" * Time: %lu ms\n\n"
), xPortGetCoreID(), result, clock);
#endif
}
}
void loop2(void*) {
while (1) {
#if TOGGLE
benchmark_write_gpio(Time_2);
Serial.printf(PSTR(
">>> BENCHMARK WRITE <<< Core: %d\n"
" * digitalWrite(): %lu ms\n"
" * gpio_set_level(): %lu ms\n"
" * GPIO.out_w1ts/t: %lu ms\n"
" * REG_WRITE(): %lu ms\n\n"
), xPortGetCoreID(), Time_2.digital, Time_2.gpio_, Time_2.GPIO, Time_2.REG);
#else
uint32_t clock = millis();
double result = benchmark_pi(10000000);
clock = millis() - clock;
Serial.printf(PSTR(
">>> BENCHMARK PI <<< Core: %d\n"
" * PI: %lf\n"
" * Time: %lu ms\n\n"
), xPortGetCoreID(), result, clock);
#endif
// I tried enclosing the `Serial.printf()` code inside this if, but it seems that `Serial` is safe even for Multi-Core
// (besides using this making nothing work in my program, maybe I implemented it wrong , I don't know...).
//
//if (xSemaphoreTake(atomic_print, pdTICKS_TO_MS(100)))
// xSemaphoreGive(atomic_print);
//vTaskDelete(NULL);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment