picogame: RP2040/RP2350 flags optimization + enable picogame on selected boards - #11358
lynt-smitka wants to merge 2 commits into
Conversation
dhalbert
left a comment
There was a problem hiding this comment.
This is good; I would just like some comment tweaks.
|
I'll rework it a bit, including adding better comments. I ran the tests for each flag separately and I have to interpret the results (the vectorization need few more tests). I hope it will be done in few hours. |
|
I meant to have this enabled for all of RP2040 -- sorry I was talking about optimization flags only. |
|
The new recommendation after heavy benchmarking individual flags:
AI summarized benchmark results: 1. Each flag on its own
Two flags do the work, and they do not overlap.
The interpreter does not move under any flag. 2. Combinations
Two flags reach Dropping 3. Outside picogame
The gains are small but they are not noise and they are not picogame: 2.3 % on alpha blending, 4. What the two flags do
It did two different things to the two calls that got faster, and only one of them is unswitching in In mode7 it is textbook. The In the blit it is not. The specialization on the flip and transpose flags already exists at This also explains a column that never moves. The unflipped blit stays at 59 to 62 microseconds in
5. What the cost model costsIt is a trade, not a free win. The one call that gets slower is
So The reason is the unrolled The same trade shows on big integers: 6. The eight
|
| added on top of the five | flash | fill_rect | fill_circle | hot functions |
|---|---|---|---|---|
-fipa-cp-clone |
+11280 | 1168 | 325 | byte-identical |
-fpeel-loops |
+24052 | 1168 | 325 | byte-identical |
-floop-unroll-and-jam |
+0 | 1177 | 332 | byte-identical |
-fsplit-loops |
+3296 | 1162 | 322 | byte-identical |
-ftree-loop-distribution |
-40 | 1176 | 332 | byte-identical |
-funroll-completely-grow-size |
does not link | |||
-fversion-loops-for-strides |
+5904 | 1162 | 322 | rewrites blit and mode7 |
-floop-interchange |
+0 | 1163 | 332 | byte-identical |
Six of the seven that link leave the drawing code untouched. -fversion-loops-for-strides is the
exception: it rewrites 985 instructions in the blit and 214 in mode7 and is still no faster.
Together with the inline parameters these are the 130 KB between the set and -O3.
|
Now I'm the one not sure of the state of this. :) |
|
I'm still finishing up a few tests. I've decided on the flags for the RP2040, but I'm still fine-tuning a similar set for the RP2350. I just need a little more time. This will also affect the choice of boards for running picogame. |
The port default was -O3. Measured flag by flag on a raspberry_pi_pico
(RP2040) and a Fruit Jam (RP2350), two of what -O3 adds over -O2 move a
benchmark; the rest costs flash and wins nothing.
-funswitch-loops +16 KB. Hoists a loop-invariant test out of
the loop and keeps one body per value. Gives
the -O3 numbers on a flipped sprite blit
(23 %) and a textured floor (9 %), and 1-2 %
on bitmaptools.alphablend and ulab reductions.
-fvect-cost-model=dynamic +4 KB. -O2 uses very-cheap, which rejects
nearly every loop; dynamic lets the vectorizer
unroll memset, memcpy and a 16-bit row fill.
Gives the -O3 numbers on rectangle fills and
bytearray copies (37 %) and on aesio (16 %).
A run shorter than its alignment prologue
loses: a four-pixel span fill is 7 % slower.
The other four -O3 loop passes tried (-fpredictive-commoning,
-fgcse-after-reload, -ftree-partial-pre, -fsplit-paths) emit the same
code as -O2 for the loops that matter and cost -168 to +2376 bytes. The
rest of -O3 is 130 KB, 92 KB of it the inline parameters, and no column
moves under it. The bytecode interpreter does not move under any flag:
py/py.mk builds gc.o and vm.o at -O3 whatever this is set to.
RP2040, raspberry_pi_pico, microseconds per call:
-O2 pair -O3
blit_flip 113 87 87
mode7 5915 5413 5406
fill_rect 1163 732 739
fill_circle 322 245 243
4 KB copy 3857 2441 2435
AES 4 KB 17248 14508 13543
vspans 3703 3945 3807
text +0 +20664 +151020
RP2350, Fruit Jam with PSRAM off so the buffers sit in SRAM, three rounds:
pair -O3
fill_circle 136 135
vspans 1666 1652
triangles 1221 1212
fill_rect 490 490
blit565 44 44
blit_flip 43 45
mode7 2623 2639
text 849004 971752
With PSRAM on, a 4 KB copy and fill, an integer loop, fib(20), bignum,
aesio, alphablend, rotozoom, fill_region, three ulab calls and an mbedtls
sha256 are all within 0.25 % of -O3.
So the pair is 130 KB smaller on RP2040 and 123 KB smaller on RP2350 at
the same speed, and one setting covers the port. pajenicko_picopad and
pimoroni_picosystem drop their board copies of the earlier five-pass set,
which would otherwise pin it with =. Boards that set -O2 or -Os keep
their setting.
54dfb12 to
d2e8349
Compare
Neither fits at -O3: pico had 48 KB free of its 1020 KB partition and pico_w 2 KB of its 1536 KB, while the engine needs 50 KB. With the port flags pico has 153 KB free and pico_w 148 KB (en_US build).
d2e8349 to
7722194
Compare
|
@dhalbert @tannewt After many measurements, I found the ideal combination of optimization flags that work great for both the RP2040 and RP2350. OPTIMIZATION_FLAGS ?= -O2 -funswitch-loops -fvect-cost-model=dynamic These flags result in massive savings of over 120 kB of flash on each board, with a performance loss of only about 1%. The only noticable penalty I measured was for AES on the RP2040, where the performance loss is 7%, but I still think that’s a great deal. I’d still like to enable picogame on a wider range of boards. I can do tin this PR or in the next one. From our discussions here and in the PR #11357, it seemed to me that you were okay with enabling it on all RP2350 boards (this PR will give the boards much more flash than picogame consumes) and on a selection of RP2040 boards - is that correct? Can I proceed that way? |
Enables picogame on raspberry_pi_pico and raspberry_pi_pico_w.
Neither fits at the port default -O3: pico has 48 KB free of its 1020 KB partition and pico_w 2 KB of its 1536 KB, while the engine needs 50 KB. Both build at -O2, which leaves around 140 KB free and measures within 1% of -O3 across the render kernels on this M0+.
pico_w sits at 99.9% today, so it builds all 17 translations on every pull request; with the flags it skips them like the other boards.