Skip to content

Commit f4a9bb8

Browse files
committed
fix: fix most known build issues
1 parent c917b6b commit f4a9bb8

25 files changed

Lines changed: 2108 additions & 6 deletions

.github/workflows/natmod.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ jobs:
7676

7777
steps:
7878
- uses: actions/checkout@v6
79+
with:
80+
submodules: recursive
7981

8082
- name: Fetch MicroPython ${{ env.MPY_TAG }}
8183
run: |
@@ -118,6 +120,8 @@ jobs:
118120
- { suffix: _dp, precision: double }
119121
steps:
120122
- uses: actions/checkout@v6
123+
with:
124+
submodules: recursive
121125

122126
- name: Fetch MicroPython ${{ env.MPY_TAG }}
123127
run: |
@@ -159,6 +163,8 @@ jobs:
159163
- { suffix: _dp, precision: double }
160164
steps:
161165
- uses: actions/checkout@v6
166+
with:
167+
submodules: recursive
162168

163169
- name: Fetch MicroPython ${{ env.MPY_TAG }}
164170
run: |
@@ -197,6 +203,8 @@ jobs:
197203
runs-on: ubuntu-latest
198204
steps:
199205
- uses: actions/checkout@v6
206+
with:
207+
submodules: recursive
200208

201209
- name: Fetch MicroPython ${{ env.MPY_TAG }}
202210
run: |

.github/workflows/usermod.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ jobs:
2323
runs-on: ubuntu-latest
2424
steps:
2525
- uses: actions/checkout@v6
26+
with:
27+
submodules: recursive
2628

2729
- name: Fetch MicroPython ${{ env.MPY_TAG }}
2830
run: |
@@ -68,6 +70,8 @@ jobs:
6870
runs-on: ubuntu-latest
6971
steps:
7072
- uses: actions/checkout@v6
73+
with:
74+
submodules: recursive
7175

7276
- name: Install QEMU user-mode emulation
7377
run: sudo apt-get install -y qemu-user
@@ -91,6 +95,8 @@ jobs:
9195
runs-on: ubuntu-latest
9296
steps:
9397
- uses: actions/checkout@v6
98+
with:
99+
submodules: recursive
94100

95101
- name: Fetch MicroPython ${{ env.MPY_TAG }}
96102
run: |
@@ -136,6 +142,8 @@ jobs:
136142
runs-on: ubuntu-latest
137143
steps:
138144
- uses: actions/checkout@v6
145+
with:
146+
submodules: recursive
139147

140148
- name: Install QEMU user-mode emulation
141149
run: sudo apt-get install -y qemu-user
@@ -159,6 +167,8 @@ jobs:
159167
runs-on: ubuntu-26.04-arm
160168
steps:
161169
- uses: actions/checkout@v6
170+
with:
171+
submodules: recursive
162172

163173
- name: Fetch MicroPython ${{ env.MPY_TAG }}
164174
run: |
@@ -200,6 +210,8 @@ jobs:
200210
runs-on: ubuntu-latest
201211
steps:
202212
- uses: actions/checkout@v6
213+
with:
214+
submodules: recursive
203215

204216
- name: Fetch MicroPython ${{ env.MPY_TAG }}
205217
run: |

bclibc

Submodule bclibc updated 49 files

benchmarks/README.md

Lines changed: 250 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,250 @@
1+
# tiny_bclibc MicroPython natmod — Benchmark Report
2+
3+
**Shot config:** G7, BC=0.310, 168 gr @ 2750 fps, zeroed at 300 m
4+
**Script:** `micropython-mod/tests/tiny_bclibc_bench.py`
5+
6+
---
7+
8+
## Cross-platform — `integrate` 1 km, 10 m steps
9+
10+
| Platform | Engine / Precision | avg ms | shots/sec | vs RP2040 SP |
11+
|---|---|---:|---:|---:|
12+
| RP2040 · Cortex-M0+ · 125 MHz · no FPU | tiny_bclibc SP | 353 ms | **2.8** ||
13+
| RP2040 · Cortex-M0+ · 125 MHz · no FPU | tiny_bclibc DP | 662 ms | **1.5** | 0.5× |
14+
| ish · iOS · i686 emu · ~25 MFLOPS | tiny_bclibc SP | 9.4 ms | **107.5** | 38× |
15+
| ish · iOS · i686 emu · ~25 MFLOPS | tiny_bclibc DP | 17.6 ms | **54.0** | 19× |
16+
| ish · iOS · i686 emu · ~25 MFLOPS | py-balcalc Cython DP | 10.1 ms | **99.2** | 35× |
17+
| x64 Linux · MicroPython unix | tiny_bclibc SP | 0.46 ms | **2,217** | 792× |
18+
| x64 Linux · MicroPython unix | tiny_bclibc DP | 1.07 ms | **980** | 350× |
19+
| x64 Linux · CPython | py-balcalc Cython DP ¹ | 0.123 ms | **8,152** | 2912× |
20+
21+
> ¹ `performance_check.py -n 10000` — different shot config / step size from tiny_bclibc bench.
22+
> See [x64 engine comparison](#x64-tiny_bclibc-vs-py-ballisticcalc-cython) for details.
23+
24+
---
25+
26+
## Cross-platform — `find_zero_angle`
27+
28+
| Platform | Engine / Precision | target | avg ms | calls/sec |
29+
|---|---|---|---:|---:|
30+
| RP2040 | tiny_bclibc SP | 300 m | 119 ms | **8.4** |
31+
| RP2040 | tiny_bclibc DP | 300 m | 337 ms | **3.0** |
32+
| ish | tiny_bclibc SP | 300 m | 2.9 ms | **331.5** |
33+
| ish | tiny_bclibc DP | 300 m | 10.1 ms | **94.9** |
34+
| ish | py-balcalc Cython DP | 300 m | 6.5 ms | **153.0** |
35+
| x64 | tiny_bclibc SP | 300 m | 0.131 ms | **7,398** |
36+
| x64 | tiny_bclibc DP | 300 m | 0.624 ms | **1,575** |
37+
| x64 | py-balcalc Cython DP ² | 300 m | 0.960 ms | **1,042** |
38+
| x64 | py-balcalc Cython DP ¹ | 100 m | 0.045 ms | **22,296** |
39+
40+
> ² `benchmark.py -r 1000 -w 100`.
41+
42+
---
43+
44+
## SP vs DP — x64 Linux (v1.1.3-10-g4a6c3b6)
45+
46+
| Benchmark | SP | DP | Ratio DP/SP |
47+
|---|---:|---:|---:|
48+
| `integrate` 1 km — avg | 0.46 ms | 1.07 ms | 2.33× |
49+
| `integrate` 3 km — avg | 2.46 ms | 5.94 ms | 2.41× |
50+
| `integrate_at` — avg | 0.062 ms | 0.217 ms | 3.50× |
51+
| `find_zero_angle` — avg | 0.131 ms | 0.624 ms | 4.76× |
52+
| `find_apex` — avg | 0.024 ms | 0.049 ms | 2.04× |
53+
| Peak heap (3 km traj) | 19,520 B | 19,520 B | 1.0× |
54+
| Free heap before | 2,032 KB | 2,012 KB | −20 KB |
55+
56+
> On x64 the SP/DP ratio is higher than on RP2040 (2.3–4.8× vs 1.9–2.8×).
57+
> SP uses bundled fdlibm (`sinf`/`cosf`/`atan2f`), DP uses bundled libm_dbl.
58+
> `find_zero_angle` hits 4.76× because the double tolerance (`1e-8`) requires
59+
> significantly more Ridder iterations than float (`1e-4`).
60+
61+
---
62+
63+
## SP vs DP — RP2040 single-core (v1.1.3-10-g4a6c3b6)
64+
65+
| Benchmark | SP | DP | Ratio DP/SP |
66+
|---|---:|---:|---:|
67+
| `integrate` 1 km — avg | 353 ms | 662 ms | 1.87× |
68+
| `integrate` 3 km — avg | 2151 ms | 4162 ms | 1.93× |
69+
| `integrate_at` — avg | 66.9 ms | 127 ms | 1.90× |
70+
| `find_zero_angle` — avg | 119 ms | 337 ms | 2.83× |
71+
| `find_apex` — avg | 33.4 ms | 63.3 ms | 1.90× |
72+
| Peak heap (3 km traj) | 10,080 B | 10,080 B | 1.0× |
73+
| Free heap before | 179,872 B | 144,912 B | −35 KB |
74+
75+
## SP vs DP — RP2040 dual-core Core1 (v1.1.3-10-g4a6c3b6)
76+
77+
| Benchmark | SP | DP | Ratio DP/SP |
78+
|---|---:|---:|---:|
79+
| `integrate` 1 km — avg | 353.23 ms | 661.73 ms | 1.87× |
80+
| `integrate` 3 km — avg | 2151.21 ms | 4161.80 ms | 1.93× |
81+
| `integrate_at` — avg | 66.949 ms | 127.042 ms | 1.90× |
82+
| `find_zero_angle` — avg | 119.104 ms | 336.923 ms | 2.83× |
83+
| `find_apex` — avg | 33.435 ms | 63.370 ms | 1.90× |
84+
| Free heap before | 170,976 B | 137,120 B | −34 KB |
85+
86+
> Single-core and Core1 results agree within <1 ms.
87+
88+
## SP vs DP — ish / i686 (v1.1.3-19-gf2b28fa)
89+
90+
| Benchmark | SP | DP | Ratio DP/SP |
91+
|---|---:|---:|---:|
92+
| `integrate` 1 km — avg | 9.44 ms | 17.62 ms | 1.87× |
93+
| `integrate` 3 km — avg | 42.79 ms | 91.63 ms | 2.14× |
94+
| `integrate_at` — avg | 1.648 ms | 3.656 ms | 2.22× |
95+
| `find_zero_angle` — avg | 2.899 ms | 10.146 ms | 3.50× |
96+
| `find_apex` — avg | 0.837 ms | 1.824 ms | 2.18× |
97+
| Free heap before | 990,704 B | 971,552 B | −19 KB |
98+
99+
---
100+
101+
## py-ballisticcalc Cython vs tiny_bclibc SP — ish / i686
102+
103+
| Metric | tiny SP | py-balcalc Cython | tiny SP advantage |
104+
|---|---:|---:|---:|
105+
| `integrate` 1 km | 9.44 ms · **107.5/s** | 10.08 ms · **99.2/s** | +8% |
106+
| `find_zero` 300 m | 2.90 ms · **331.5/s** | 6.54 ms · **153.0/s** | +116% |
107+
108+
> `benchmark.py` (different config): Cython Trajectory 28.18 ms, Zero 48.27 ms.
109+
110+
---
111+
112+
## x64: tiny_bclibc vs py-ballisticcalc Cython
113+
114+
Two different benchmark scripts — configs are **not identical**, numbers are indicative only.
115+
116+
### `benchmark.py -r 1000 -w 100` (py-balcalc, v2.3.0b3, warmed up)
117+
118+
| Case | py-balcalc Cython | tiny_bclibc SP | tiny_bclibc DP |
119+
|---|---:|---:|---:|
120+
| Trajectory 1 km | 0.334 ms · **2,994/s** | 0.459 ms · **2,217/s** | 1.068 ms · **980/s** |
121+
| Zero | 0.960 ms · **1,042/s** | 0.131 ms · **7,398/s** | 0.624 ms · **1,575/s** |
122+
123+
> tiny_bclibc SP is **7.1× faster** at zero-finding; py-balcalc is **1.4× faster** at trajectory
124+
> (likely due to coarser output step or different integration config).
125+
126+
### `performance_check.py -n 10000` (py-balcalc, v2.3.0b3, 10k iters)
127+
128+
| Case | py-balcalc Cython | tiny_bclibc SP | tiny_bclibc DP |
129+
|---|---:|---:|---:|
130+
| Trajectory 1 km | 0.123 ms · **8,152/s** | 0.459 ms · **2,217/s** | 1.068 ms · **980/s** |
131+
| Trajectory 1 km + extra | 0.132 ms · **7,598/s** |||
132+
| integrate_at 1 km | 0.054 ms · **18,475/s** | 0.062 ms · **16,159/s** | 0.217 ms · **4,524/s** |
133+
| Zero 100 m | 0.045 ms · **22,296/s** | 0.131 ms · **7,398/s** ³ | 0.624 ms · **1,575/s** ³ |
134+
135+
> ³ tiny_bclibc zeros at 300 m, py-balcalc at 100 m — fewer Ridder iterations for shorter distance.
136+
137+
`integrate_at` is the most comparable call (same target: 1 km, no step-size differences).
138+
tiny_bclibc SP (0.062 ms) is on par with py-balcalc Cython (0.054 ms) — 15% slower.
139+
140+
---
141+
142+
## Analysis
143+
144+
**x64 (SSE2 FPU, bundled math):** SP uses fdlibm (`sinf`/`cosf`), DP uses libm_dbl.
145+
The SP/DP ratio is 2.3–4.8× — larger than on RP2040 (1.9–2.8×) because the
146+
float libm path is proportionally much lighter than the double path on x64.
147+
`find_zero_angle` shows the biggest gap (4.76×): tighter double convergence tolerance
148+
demands more inner `integrate` calls per root iteration.
149+
150+
**RP2040 (Cortex-M0+, newlib, no FPU):** Both precisions are software via newlib.
151+
DP uses 8-byte operands → ~1.9× slower across most paths. `find_zero_angle` is
152+
2.83× due to tighter convergence tolerance.
153+
154+
**ish / i686 (~25 MFLOPS):** x87 FPU running under iOS emulation. SP is ~38× faster
155+
than RP2040 SP; DP ~19× faster than RP2040 DP. `find_zero_angle` shows 3.50× DP/SP
156+
ratio — between RP2040 and x64.
157+
158+
**Numerical accuracy:**
159+
All platforms agree on elevation (`0.1434°` on x64 / RP2040, `0.1426–0.1428°` on ish
160+
due to different libm version). Apex `532.1 ft / 0.6 ft` on x64 and RP2040.
161+
SP and DP give identical visible results — float32 is sufficient for ≤ 3 km range.
162+
163+
**Recommendation:**
164+
- RP2040: SP — 1.9–2.8× faster, identical accuracy.
165+
- x64 / server: DP when maximum accuracy needed, SP for throughput-critical paths.
166+
- ish / i686: SP already outperforms Cython engine; DP available for validation.
167+
168+
---
169+
170+
## FPU raw throughput — platform comparison
171+
172+
Benchmark: scalar FP add+multiply loop, native C
173+
(RP2040: native `.mpy`; ish/x64: `gcc -O2 -march=native`).
174+
175+
| Platform | Mode | DP MFLOPS | SP MFLOPS | SP/DP |
176+
|---|---|---:|---:|---:|
177+
| RP2040 · Cortex-M0+ · 125 MHz · no FPU | latency-bound (volatile chain) | 0.52 | 1.10 | 2.12× |
178+
| RP2040 · Cortex-M0+ · 125 MHz · no FPU | throughput (8 accumulators) | **1.41** | **2.21** | 1.57× |
179+
| ish · iOS · i686 emu | latency-bound (volatile chain) | 41.6 | 39.6 | 0.95× |
180+
| ish · iOS · i686 emu | throughput (8 accumulators) | **853** | **1,449** | 1.70× |
181+
| x64 Linux · AMD Ryzen 7 8845HS | latency-bound (volatile chain) | 668 | ~720 | ~1.1× |
182+
| x64 Linux · AMD Ryzen 7 8845HS | throughput (8 accumulators) | **23,214** | **23,451** | 1.01× |
183+
184+
> **Latency-bound** (`volatile c; c = c + a*b; c = c - a*b`) — sequential dependency chain,
185+
> no ILP; measures FPU/soft-float latency + stack/L1 round-trip.
186+
> **Throughput** (8 independent accumulators) — variables kept in registers, partial
187+
> pipeline overlap possible.
188+
189+
**Key observations:**
190+
- RP2040 latency DP = **0.52 MFLOPS** — volatile stack spills + soft-float `__muldf3`/`__adddf3`
191+
(~200 cycles each). Throughput/latency ratio: DP **2.7×**, SP **2.0×** — even on soft-float,
192+
8 independent accumulators help by eliminating volatile spills and allowing partial call pipelining.
193+
- ish latency (~40 MFLOPS) reflects x87 dispatch overhead under iOS ARM emulation; actual
194+
throughput is **853 MFLOPS DP / 1,449 MFLOPS SP**.
195+
- On ish, SP is **1.7×** faster than DP — x87 processes DP internally in 80-bit, costlier under ARM emulation.
196+
- On x64, SP ≈ DP — both go through SSE2/AVX2 with equal pipeline width.
197+
- x64 throughput exceeds RP2040 by **16,500× (DP)** and **10,600× (SP)**.
198+
199+
---
200+
201+
## Summary — all platforms, all engines (calls/sec, higher = better)
202+
203+
> ⚠ py-ballisticcalc and tiny_bclibc use **different shot configs and step sizes**
204+
> — numbers are not strictly apples-to-apples except for `integrate_at` (same 1 km target).
205+
206+
| Platform | Engine | `integrate` 1 km/s | `integrate_at` /s | `find_zero` 300 m/s | `find_apex` /s |
207+
|---|---|---:|---:|---:|---:|
208+
| RP2040 · armv6m · 125 MHz · no FPU | tiny_bclibc **SP** | **2.8** | **15** | **8.4** | **30** |
209+
| RP2040 · armv6m · 125 MHz · no FPU | tiny_bclibc DP | 1.5 | 8 | 3.0 | 16 |
210+
| ish · iOS · i686 emu · ~25 MFLOPS | tiny_bclibc **SP** | **107.5** | **607** | **331.5** | **1,195** |
211+
| ish · iOS · i686 emu · ~25 MFLOPS | tiny_bclibc DP | 54.0 | 274 | 94.9 | 548 |
212+
| ish · iOS · i686 emu · ~25 MFLOPS | py-balcalc Cython DP ¹ | 99.2 | 255 | 153.0 ² ||
213+
| x64 Linux · MicroPython unix | tiny_bclibc **SP** | **2,217** | **16,159** | **7,398** | **41,667** |
214+
| x64 Linux · MicroPython unix | tiny_bclibc DP | 980 | 4,524 | 1,575 | 20,408 |
215+
| x64 Linux · CPython | py-balcalc Cython DP ³ | 2,994 | 18,475 | 1,042 ⁴ ||
216+
217+
> ¹ `performance_check.py -n 120` (ish).
218+
> ² py-balcalc zeros at **100 m** on ish (performance_check.py), not 300 m.
219+
> ³ `benchmark.py -r 1000 -w 100` for trajectory/zero; `performance_check.py -n 10000` for integrate_at.
220+
> ⁴ py-balcalc zeros at **300 m** here (benchmark.py).
221+
222+
**Key takeaways:**
223+
- `integrate_at` is the most directly comparable call: tiny_bclibc SP is within **15%** of Cython on x64, and **2.4×** faster on ish.
224+
- `find_zero` 300 m: tiny_bclibc SP beats Cython by **7.1×** on x64 and **2.2×** on ish (300 m vs 100 m).
225+
- RP2040 SP is **792×** slower than x64 SP — expected for Cortex-M0+ soft-float vs SSE2.
226+
- SP vs DP overhead grows with algorithm complexity: `integrate` ~1.9–2.3×, `find_zero` 2.8–4.8×.
227+
228+
---
229+
230+
## Raw logs
231+
232+
### tiny_bclibc natmod
233+
234+
| File | Platform | Prec |
235+
|---|---|---|
236+
| [`tiny_bclibc_natmod_bench_x64_sp.log.txt`](tiny_bclibc_natmod_bench_x64_sp.log.txt) | x64 Linux | SP |
237+
| [`tiny_bclibc_natmod_bench_x64_dp.log.txt`](tiny_bclibc_natmod_bench_x64_dp.log.txt) | x64 Linux | DP |
238+
| [`tiny_bclibc_natmod_bench_ish_sp.log.txt`](tiny_bclibc_natmod_bench_ish_sp.log.txt) | ish / iOS / i686 | SP |
239+
| [`tiny_bclibc_natmod_bench_ish_dp.log.txt`](tiny_bclibc_natmod_bench_ish_dp.log.txt) | ish / iOS / i686 | DP |
240+
| [`tiny_bclibc_natmod_bench_sp.log.txt`](tiny_bclibc_natmod_bench_sp.log.txt) | RP2040 single-core | SP |
241+
| [`tiny_bclibc_natmod_bench_dp.log.txt`](tiny_bclibc_natmod_bench_dp.log.txt) | RP2040 single-core | DP |
242+
| [`tiny_bclibc_natmod_bench_2core.log.txt`](tiny_bclibc_natmod_bench_2core.log.txt) | RP2040 dual-core (Core1) | SP |
243+
| [`tiny_bclibc_natmod_bench_2core_dp.log.txt`](tiny_bclibc_natmod_bench_2core_dp.log.txt) | RP2040 dual-core (Core1) | DP |
244+
245+
### py-ballisticcalc CythonizedRK4
246+
247+
| File | Platform |
248+
|---|---|
249+
| [`py_balcalc_cython_bench_x64.log.txt`](py_balcalc_cython_bench_x64.log.txt) | x64 Linux (benchmark.py + performance_check.py) |
250+
| [`py_balcalc_cython_bench_ish.log.txt`](py_balcalc_cython_bench_ish.log.txt) | ish / iOS / i686 |

benchmarks/flops_bench/Makefile

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
ARCH ?= armv6m
2+
MPY_DIR ?= ../../micropython-mod/natmod/micropython
3+
4+
MOD := _flops_bench_$(ARCH)
5+
SRC := flops_bench_natmod.c
6+
BUILD := build/$(ARCH)
7+
8+
# ARM soft-float builtins (__mulsf3, __addsf3, etc.) come from newlib via LINK_RUNTIME
9+
ifeq ($(ARCH),$(filter $(ARCH),armv6m armv7m armv7emsp armv7emdp))
10+
LINK_RUNTIME = 1
11+
endif
12+
13+
ifeq ($(wildcard $(MPY_DIR)/py/dynruntime.mk),)
14+
$(error MPY_DIR="$(MPY_DIR)" not found — set MPY_DIR=/path/to/micropython)
15+
endif
16+
include $(MPY_DIR)/py/dynruntime.mk
17+
18+
dist: all
19+
$(Q)mkdir -p $(BUILD)
20+
$(Q)mv $(MOD).mpy $(BUILD)/_flops_bench.mpy
21+
$(ECHO) "$(BUILD)/_flops_bench.mpy"
22+
23+
clean:
24+
rm -rf build

0 commit comments

Comments
 (0)