Some questions about micropython speed

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
Post Reply
pipponefrancone
Posts: 9
Joined: Sat Sep 12, 2020 6:02 pm

Some questions about micropython speed

Post by pipponefrancone » Sat Sep 12, 2020 6:30 pm

Hello everybody! :)
I've discovered micropython a few weeks ago and I am just loving it! I've recently been working on a hexapod robot and I am currently controlling it with a rasberry pi. Since the code is writted in python and I want the robot to be wirelessly controlled, I thought that a esp32 running micropython could do the job. The only problem: the code is really slow. I have already tryed optimizing it different times and managed to cut about 20ms off, but it still takes about 35 milliseconds per iteration on an esp32, and I have yet to implement all the wi-fi code! For a real-time robot that needs to be constantly fed new servo positions 35ms is not ideal (on the pi the same unoptimized code runs at ~20ms). So I would like to ask some questions about code optimization.

- Is there a way to speed up I2C? I am using x2 pca9685 to control the servos, and about 15ms of the total execution time goes to controlling the boards. I am using the adafruit library for the pca9685.

- There are functions that gets called again and again during one execution, so beeing able to compile those as .mpy files or rewrite them in C would be great for speed. Is there any beginner-friendly documentation/guide on how to do it?

- How can I achieve RC like performances using wi-fi? What protocol is best suited for live data streaming across devices?

Any sources or links to learn more about any of those topics is greatly appreciated. Thanks in advantance :D

User avatar
Roberthh
Posts: 2236
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: Some questions about micropython speed

Post by Roberthh » Sat Sep 12, 2020 6:49 pm

Some answers to your questions:

Pre-compiling code as .mpy files does only speed up loading time, not execution time.
For Speeding up the code there are a few options, which are very good described in the manual: http://docs.micropython.org/en/latest/r ... ython.html
For I2C you can try to change the baud rate of the call. You should expect the best performance with the hardware I2C devices. If you do ot do already, try the fast I2C mode of the PCA9685. But I would assume that it's not the baud rate which us the limiting factor.

Generally the ESP32 is not the most responsive design when it comes to servicing hardware. Out of the micropython board family, the Pyboard D series are faster and more responsive, but obviously much more expensive.

User avatar
rcolistete
Posts: 326
Joined: Thu Dec 31, 2015 3:12 pm
Location: Brazil
Contact:

Re: Some questions about micropython speed

Post by rcolistete » Sat Sep 12, 2020 8:45 pm

See this post at topic "ulab, or what you will - numpy on bare metal" citing a FFT benchmark comparing many MicroPython boards. My suggestions to speed up :
- share your MicroPython so the community can try to suggest some specific optimizations;
- as pointed by @Roberthh, try to use @micropython.native and @micropython.viper decorators in some parts of the code;
- if you stick with ESP32 :
* oficial MicroPython uses as default clock at 160 MHz, so change to 240 MHz -> speed increases about 50%;
* use ESP32 board without PSRAM, or a MicroPython firmware without PSRAM support on a ESP32 with PSRAM -> speed increases about 50%;
- use Pyboard D SF2 @ 216 MHz, 50% faster than ESP32 without PSRAM @ 240 MHz, and a lot faster than ESP32 when using interrupts, timers, ADC, etc;
- use MAixBiT with Lobo fw v202002, with 8MB of RAM and native FP64 (double precision), but it doesn't have WiFi/BT and ADC -> 50% faster than ESP32 without PSRAM @ 240 MHz;
- use OpenMV H7 with OpenMV firmware, with great camera hardware and software support, 3.85x the speed of an ESP32 without PSRAM @ 240 MHz, but it doesn't have WiFi/BT.
The above numbers are based on FFT benchmark with float point numbers. Your software will have different ratios when running on these boards.
My "MicroPython Samples". My "MicroPython Firmwares" with many options (double precision, ulab, etc).

User avatar
pythoncoder
Posts: 4658
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Some questions about micropython speed

Post by pythoncoder » Sun Sep 13, 2020 9:29 am

Another general comment: if you have a choice, SPI is much faster than I2C.
Peter Hinch

pipponefrancone
Posts: 9
Joined: Sat Sep 12, 2020 6:02 pm

Re: Some questions about micropython speed

Post by pipponefrancone » Sun Sep 13, 2020 5:12 pm

First of all I would like to thank you all for the super fast support that I received. :D
rcolistete wrote:
Sat Sep 12, 2020 8:45 pm
- if you stick with ESP32 :
* oficial MicroPython uses as default clock at 160 MHz, so change to 240 MHz -> speed increases about 50%;
* use ESP32 board without PSRAM, or a MicroPython firmware without PSRAM support on a ESP32 with PSRAM -> speed increases about 50%;
Onto the code stuff:
I noticed your custom micropython firmware builds, and I tried using the one supporting ulab (Since there's a lot of matrix binary operations in the code). For some reasons though, I couldn't get any performance boost out of it. I am not new to programming, but I am kinda new to python programming, especially when dealing with low level control and optimization. I couldn't even get a speed increase by changing the CPU freq (from 21ms to about 19ms execution time). Unfortunately my inexperience is turning the code into a giant ugly mess...

I would be extremely happy to share every bit of my project with the community, so that I can get help for anyone who's willing to contribute. I'll keep this thread updated with the github page when ready. In the meantime, thanks everybody! This is a great community! :D

User avatar
jimmo
Posts: 2015
Joined: Tue Aug 08, 2017 1:57 am
Location: Sydney, Australia
Contact:

Re: Some questions about micropython speed

Post by jimmo » Mon Sep 14, 2020 11:47 pm

This video from PyCon AU might give you some extra pointers on performance stuff -- https://www.youtube.com/watch?v=hHec4qL00x0

Probably the most useful thing to start with is to measure what's taking the most time. Use time.ticks_us and time.ticks_diff to measure each individual part of your loop.

User avatar
jimmo
Posts: 2015
Joined: Tue Aug 08, 2017 1:57 am
Location: Sydney, Australia
Contact:

Re: Some questions about micropython speed

Post by jimmo » Mon Sep 14, 2020 11:49 pm

pipponefrancone wrote:
Sun Sep 13, 2020 5:12 pm
I tried using the one supporting ulab (Since there's a lot of matrix binary operations in the code). For some reasons though, I couldn't get any performance boost out of it.
Are you saying you noticed no performance difference moving from the matrix maths being implemented in Python to moving to ulab's implementation? That's surprising!! Would be interested to see measurements, but I guess that suggests that your time is entirely being spent somewhere else.

pipponefrancone
Posts: 9
Joined: Sat Sep 12, 2020 6:02 pm

Re: Some questions about micropython speed

Post by pipponefrancone » Tue Sep 15, 2020 8:11 pm

jimmo wrote:
Mon Sep 14, 2020 11:49 pm
Are you saying you noticed no performance difference moving from the matrix maths being implemented in Python to moving to ulab's implementation? That's surprising!! Would be interested to see measurements, but I guess that suggests that your time is entirely being spent somewhere else.
I am 100% doing something wrong. Unfortunately ulab has no support for matmul (As far as I know), so I coded my own matmul function and I just replaced the list comprehension addictions/subtractions with the ulab +/- operators. Got no speed improvement. The problem may lie in the conversion from list to ndarray, since it takes some time.

I also took measures of the execution times and I observed no real "bottleneck". The core functions all take about 1-2ms to run (matrix multiplication, inverse kinematics, clamping and mapping functions, sigmoid). The problem is that they are executed a lot of times per iteration (IK is called once per leg; matmul is called twice per leg; all the other functions are called multiple times per leg, and there are a total of 6 legs to run through for each iteration). That eventually sums up to a lot of computation time.

But as I said, I am working on a github page where I am gonna be posting all the code, hoping to get some help from the community :)
I'll keep this thread updated. ;)

User avatar
jimmo
Posts: 2015
Joined: Tue Aug 08, 2017 1:57 am
Location: Sydney, Australia
Contact:

Re: Some questions about micropython speed

Post by jimmo » Tue Sep 15, 2020 11:24 pm

pipponefrancone wrote:
Tue Sep 15, 2020 8:11 pm
Unfortunately ulab has no support for matmul (As far as I know),
Oh! Yeah that's going to be a problem!

That seems like a really useful feature to add to ulab -- perhaps raise an issue at https://github.com/v923z/micropython-ulab/issues

(This is why we added the INPLACE_MAT_MULTIPLY and MAT_MULTIPLY binary ops (i.e. the @ operator) to MicroPython)

FWIW, the "other" micro-numpy does support this -- maybe worth checking out https://github.com/nickovs/uumpy/

Edit: ulab does support matrix multiply -- https://micropython-ulab.readthedocs.io ... b.html#dot it just doesn't support the @ operator.

pipponefrancone
Posts: 9
Joined: Sat Sep 12, 2020 6:02 pm

Re: Some questions about micropython speed

Post by pipponefrancone » Thu Sep 17, 2020 5:32 pm

jimmo wrote:
Tue Sep 15, 2020 11:24 pm
Edit: ulab does support matrix multiply -- https://micropython-ulab.readthedocs.io ... b.html#dot it just doesn't support the @ operator.
Oh How did i miss that :? Thank you!

Post Reply