pimoroni / badger2040

Examples and firmware for Badger 2040 and Badger 2040 W
MIT License
150 stars 50 forks source link

MicroPython Startup Benchmarks #10

Open Gadgetoid opened 1 year ago

Gadgetoid commented 1 year ago

As part of the discovery process for dropping our complex Pico SDK runtime patches, I ran some tests of startup times under the following conditions:

  1. vsys high to GPIO 15 high (set by MicroPython)
  2. vsys high to GPIO 14 high (set by C++)
  3. vsys high to GPIO 12 high (set by our pico_runtime/runtime.c patch)

I also tested the first two cases with and without our clock config patches.

Basic clock config patch: https://github.com/pimoroni/badger2040/blob/v0.0.2/firmware/startup_overclock.patch

Full runtime patch: https://github.com/pimoroni/pimoroni-pico/blob/v1.19.18/micropython/_board/picow_enviro/wakeup_gpio.patch

Findings:

  1. Overclock makes more of a difference to startup time than moving from MicroPython to C++ -

    • from MicroPython to C++ is 50ms faster
    • raising clock early: MicroPython is 87.6ms faster
    • raising clock early: C++ is 88ms faster
    • raising clock early: gains ~88ms in both cases
  2. Moving from C++ to pico_runtime/runtime.c is much faster again

    • vsys high to GPIO set MicroPython: 77.6ms
    • vsys high to GPIO set C++: 26.8ms
    • vsys high to GPIO set pico_runtime/runtime.c: 8.2ms

If we want to read or set GPIO earlier than 26ms from power-on, we must patch pico_runtime/runtime.c and run our code before all the other bring-up.

A plain C++ approach gets us around 26.8ms to pin read. This is fine for Badger 2040 and actually functions as a sort-of debounce.

Summary

Setting a pin in MicroPython will take ~77ms from power on in the absolute best case. A larger MicroPython main.py with more complicated code will affect this.

Setting a pin in C++ (using __attribute__ ((init_priority (101))) on a struct instance) will take ~27ms from power on in the absolute best case. Adding any other C++ modules that are init before the wakeup module will affect this. (Though I have taken pains to remove all C++ init since it will try to allocate memory.)

Captures

VSys to GPIO15 High: MicroPython

pico-w-vanilla-startup-vsys-micropython-gpio15-high pico-w-vanilla-startup-vsys-micropython-gpio15-high-overclocked

VSys to GPIO14 High: C++

pico-w-vanilla-startup-vsys-cpp-gpio14-high pico-w-vanilla-startup-vsys-cpp-gpio14-high-overclocked

VSys to GPIO12 High: pico_runtime/runtime.c patch

pico-w-vanilla-startup-vsys-runtime-gpio12-high-overclocked-zoomed