|
Forum Index : Microcontroller and PC projects : Armmite vs MicroPython performance
| Author | Message | ||||
| sawasdee01 Newbie Joined: 23/12/2016 Location: United KingdomPosts: 33 |
Hi All, I have been testing both Micropython and Armmite images on the Nucleo STM32L476RG board in an attempt to gain an insight into the relative performance of the two languages on an identical hardware platform. For interest, I have some early results for your perusal, below. A quick disclaimer, first:- I would describe myself as an 'absolute beginner' with respect to Micropython. Also, I have not taken any steps with either platform to optimise code, etc - although, I have used Integer variables, throughout (ie no floats, etc). Versions Armmite Version:- 2019-03-19_232030_Armmite_L4 MicroPython Version:- NUCLEO_L476RG-20190330-v1.10-247-g0fb15fc3f_00 Approach In order to keep the testing technique as 'non-invasive' as possible, I used a Bitscope BS5U oscilloscope attached to PA5 (pin 21). Each test was performed within a Do While(1) loop. The first instruction inside the loop set Port pin PA5 high. After the measurement period, the Port pin PA5 was set low. Time measurements were read from the oscilloscope Test Number 1 - Simple Toggle Port Pins Armmite Code CONST PA5=21 SETPIN PA5,DOUT DO WHILE(1) Pin(PA5)=1 Pin(PA5)=0 LOOP Micropython Code (note LED_GREEN is on PA5 and is already defined in the board Micropython package) import machine import sys led = machine.Pin('LED_GREEN',machine.Pin.OUT) led.value(1) while True: led.value(1) led.value(0) Results MicroPython PA5 high time = 17 microSecs PA5 low time 17 microSecs Armmite PA5 high time = 58 microSecs PA5 low time 92 microSecs Test Number 2 - Toggle Port Pins with Integer Add Armmite Code DIM A%=42 DIM B%=6 DIM C%=10 DIM D%=2 DIM SUM% CONST PA5=21 SETPIN PA5,DOUT DO WHILE(1) Pin(PA5)=1 SUM%=A%+B% Pin(PA5)=0 SUM%=C%+D% LOOP Micropython Code import machine import sys a=int(42) b=int(6) c=int(10) d=int(2) x=int(0) y=int(0) led = machine.Pin('LED_GREEN',machine.Pin.OUT) led.value(1) while True: led.value(1) x=a+b led.value(0) y=c+d MicroPython PA5 high time = 29 microSecs PA5 low time 29 microSecs Armmite PA5 high time = 133 microSecs PA5 low time 164 microSecs Note:- I repeated the test using subtraction, instead of addition. On the Micropython board, the results were identical to the above. I did not repeat the test on the Armmite board. Test Number 3 - Toggle Port Pins with Integer Divide The previous test was repeated with integer divides (eg x=a/b). The following results were obtained:- MicroPython PA5 high time = 32 microSecs PA5 low time 32 microSecs Armmite PA5 high time = 155 microSecs PA5 low time 193 microSecs Test Number 4 - Toggle Port Pins with empty FOR NEXT loop Armmite Code DIM A% DIM B% CONST PA5=21 SETPIN PA5,DOUT DO WHILE(1) Pin(PA5)=1 FOR A%=0 TO 5 NEXT Pin(PA5)=0 FOR B%=0 TO 5 NEXT LOOP Micropython Code import machine import sys x=int(0) y=int(0) led = machine.Pin('LED_GREEN',machine.Pin.OUT) led.value(1) while True: led.value(1) for x in range(5): pass led.value(0) for y in range(5): pass MicroPython PA5 high time = 93 microSecs PA5 low time 93 microSecs Armmite PA5 high time = 207 microSecs PA5 low time 244 microSecs Conclusion I suspect that Micropython behaves somewhat differently to Armmite, as there may be a partial, or even full compilation to bytecode, when programs are downloaded over the USB / REPL (ie serial) link to the board. This MAY explain some of the speed improvements. I would be very interested to hear thoughts, views, etc. On a more general note, although Micropython is eminently usable, the overall user experience does seem a little 'rough and ready' at times. For instance, uPyCraft seems to be the 'go to' simple IDE for Micropython, at the moment. Although, uPyCraft works, it seems pretty basic and unpolished when compared to MMEdit. I suspect that Python (as opposed to MicroPython) has far better tools. I am a bit of a fan of Eclipse and at some point, I will load up the PyDev Eclipse plugin and see if I can get a better MicroPython dev environment. One final thought - IMHO the use of white space instead of code block start and end chars is a gimmick, which is already coming back to bite bottoms. The moment that code has to be uploaded across a serial connection, as in the case of Micropython, which is inevitably developed on a serially connected host, the problems start. This may be why there appear to be so few good IDEs for Micropython (as opposed to Python). My suspicion is that the original authors wanted something to make Python stick out from the crowd (especially, javascript), so the tabs/whitespace thing was invented. Now everyone seems to think that it is a wonderful way to enforce proper structure in programs. Interestingly, just placing the Micropython code into this post royally b*****s the code indentation / whitespace - meaning that the code posted here won't actually work! I wonder what size of trousers the emperor is wearing, today? Sawasdee |
||||
| matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 10572 |
Interesting. Did you set CPU 80 on the Armmite? I assume Micropython is running the uP at full speed? Did you have to build Micropython? I keep meaning to have a play but can't be bothered setting up a build environment - just need a .bin file to load. The whole support environment for Micropython seems a bit opaque but this may be just me being lazy. |
||||
| JohnL Senior Member Joined: 10/01/2014 Location: SeychellesPosts: 128 |
Link to more popular binaries. STM upload is in DFU serial bootloader mode. http://micropython.org/download http://micropython.org/ |
||||
Grogster![]() Admin Group Joined: 31/12/2012 Location: New ZealandPosts: 9755 |
If MicroPython compiles down to C, then it will run much faster then MMBASIC, which will always have the interpreter overhead to slow things down. ![]() However, MMBASIC on the Arm processor is so fast as to not be a problem for all but the fastest of requirements. Smoke makes things work. When the smoke gets out, it stops! |
||||
| sawasdee01 Newbie Joined: 23/12/2016 Location: United KingdomPosts: 33 |
Hi All, Ref "Interesting. Did you set CPU 80 on the Armmite?" in Matherp's post. Excellent point and many thanks. I have repeated the tests with CPU 80 placed at the front of each Armmite test fragment and the new results are below:- (Note:- please see test code used in the first post of this topic) Results with CPU 80 added to Armmite Test Number 1 - Simple Toggle Port Pins MicroPython PA5 high time = 17 microSecs PA5 low time 17 microSecs Armmite PA5 high time = 40 microSecs PA5 low time 65 microSecs Test Number 2 - Toggle Port Pins with Integer Add MicroPython PA5 high time = 29 microSecs PA5 low time 29 microSecs Armmite PA5 high time = 90 microSecs PA5 low time 114 microSecs Test Number 3 - Toggle Port Pins with Integer Divide MicroPython PA5 high time = 32 microSecs PA5 low time 32 microSecs Armmite PA5 high time = 108 microSecs PA5 low time 133 microSecs Test Number 4 - Toggle Port Pins with empty FOR NEXT loop MicroPython PA5 high time = 93 microSecs PA5 low time 93 microSecs Armmite PA5 high time = 142 microSecs PA5 low time 165 microSecs Conclusion Setting the the Armmite CPU to 80 Mhz definitely helps to close the gap, but Micropython is still faster. I had a quick look at the Nucleo 476RG board specific C source code on the micropython.org github. Unfortunately, whilst I found many #defines for setting the HSE and HSI, I could not see which of these #defines were actually being used in the Nucleo L476RG implementation. The comments seem to suggest that this is all done in a file called something like RCC HAL. I could not find anything that looked like RCC HAL. At some point, I will load the project up into Eclipse/Atollic and do a 'search project' to find out where these #defines are being used. However, sense would suggest that Micropython runs at full clock speed on this Micropython implementation - so, my guess is that the performance comparison is now fair. BTW Apparently. I can use the Micropython machine.freq() call to find out the configured CPU frequency and I will do this when I next load up the uPython image. Ref "The whole support environment for Micropython seems a bit opaque" in Matherp's post. From my early experiences, I think that this is a fair comment. I quite like the language itself - there is a lot of functionality and the functionality is presented in a fairly understandable and clear implementation. At first, the Micropython.org website documentation looks promising, but you soon realise that it assumes that you already have a very strong foundation knowledge of Python. Eg, the second topic in the section called 'The Micropython Language' is 'Writing Interrupt Handlers' ..... gulp! Additionally, while there are a number of core micropython libraries provided for (eg) Spi, I2C, etc. The moment that you want to connect to (for example) a TFT display, you are most likely into googling for and then downloading a TFT hardware specific driver that some bloke called Fred wrote for the ESP8266 in 2016, in the vague hope that it might port onto your hardware and (presumably) talk nicely to the Micropython spi and framebuffer libraries. So, at the moment, I think that MMBasic / Armmite etc is leagues ahead in the 'ease of use / everything in one place / good documentation' game. A company called Pycom.io has recognised this and seems to be heading in a good direction - but unfortunately, their platform locks you into their ESP32 based hardware, which is not much good if you want to use the STM32L476/496. Personally, a big win for Micropython seems to be the ability to relatively easily (yeah, right!) extend Micropython using C. Like many languages, this requires a complete re-compilation of the source. At some point in the near future, I will try to load up the Nucleo 476RG Micropython source into my Atollic STM32 C compiler and see if I can re-compile it. In theory, this should work, as Atollic is based on GCC. If not, I will have to load up Linux to get the recommended GCC cross development environment. Best wishes. Sawasdee |
||||
| sawasdee01 Newbie Joined: 23/12/2016 Location: United KingdomPosts: 33 |
Hi Grogster, I am fairly sure that Micropython does not compile to either C or machine code, as it is billed as an interpreted / script like language. There are obviously big differences between Python and Micropython, as Micropython implies a cross-development platform (ie non-native). However, from the fairly limited information that I have been able to find, it would seem that Micropython is compiled to a bytecode representation (maybe, when passed over the REPL?), which is then executed by some form of Micropython VM, running on the target. This may explain why I can't seem to find anything that looks like the Basic LIST command, on the target. At a very raw guess, the results for a fully compiled (to machine code) version of Test 1 (Simple Toggle Ports) would be PA5 high time < 1 microSecs PA5 low time < 1 microSecs This would seem to support the notion that Micropython is having to execute a bytecode -> VM architecture. Best wishes and many thanks. Sawasdee |
||||
| The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |