-
-
Notifications
You must be signed in to change notification settings - Fork 7.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
py: convert None/False/True to small immediate values #5429
Conversation
Very cool! I had the idea earlier of increasing the number of bits used for the object tag in order to add a new tag for those objects, but I thought it was too far to go. Reusing the qstr tags for the price of reducing the bits for qstrs (which anyway don't make any use of the full bits) is a good trade-off. |
I also thought about this but it'd mean aligning all static/ROM objects to 8 bytes (so the 3 lower bits of the pointer are 0) which would likely lead to code size increases. |
0d843c2
to
c03f115
Compare
986a01e
to
b2e1175
Compare
b2e1175
to
8f8bd32
Compare
This commit adjusts the definition of qstr encoding in all object representations by taking a single bit from the qstr space and using it to distinguish between qstrs and a new kind of literal object: immediate objects. In other words, the qstr space is divided in two pieces, one half for qstrs and the other half for immediate objects. There is still enough room for qstr values (29 bits in representation A on a 32-bit architecture, and 19 bits in representation C) and the new immediate objects can be used for things like None, False and True.
This option (enabled by default for object representation A, B, C) makes None/False/True objects immediate objects, ie they are no longer a concrete object in ROM but are rather just values, eg None=0x6 for representation A. Doing this saves a considerable amount of code size, due to these objects being widely used: bare-arm: -392 -0.591% minimal x86: -252 -0.170% [incl +52(data)] unix x64: -624 -0.125% [incl -128(data)] unix nanbox: +0 +0.000% stm32: -1940 -0.510% PYBV10 cc3200: -1216 -0.659% esp8266: -404 -0.062% GENERIC esp32: -732 -0.064% GENERIC[incl +48(data)] nrf: -988 -0.675% pca10040 samd: -564 -0.556% ADAFRUIT_ITSYBITSY_M4_EXPRESS Thanks go to @Jongy aka Yonatan Goldschmidt for the idea.
This function is called often and with immediate objects enabled it has more cases, so optimise it for speed. With this optimisation the runtime is now slightly faster with immediate objects enabled than with them disabled.
8f8bd32
to
4005760
Compare
This has now been merged. Thanks @Jongy for the great idea! |
[micropython#4701] Correct DAC clock speed comments for SAMD21 and SAMD51
Based on discussion in #5314, with full credit to @Jongy for the idea:
That's what's done in this PR, to make
None
,False
andTrue
small immediate values, namelyMP_OBJ_NONE
,MP_OBJ_FALSE
,MP_OBJ_TRUE
.I had to steal some of the qstr encoding space in an object (see change to py/mpconfig.h) to encode these new values, so they were separate from true object pointers. But it turned out pretty neat and straightforward to do it. Hardly any places in the code assume anything about the None/False/True objects so they can easily become immediate values.
There are significant size reductions to ports:
Note that I only made it work for object representation A at this point. Also, did not do any performance comparison tests with the changes.