Skip to content

fix(build): default to a Release build type - #413

Open
youtalk wants to merge 1 commit into
autowarefoundation:mainfrom
youtalk:fix/build-default-release
Open

youtalk wants to merge 1 commit into
autowarefoundation:mainfrom
youtalk:fix/build-default-release

Conversation

@youtalk

@youtalk youtalk commented Sep 10, 2026

Copy link
Copy Markdown
Member

What

Default CMAKE_BUILD_TYPE to Release when the user has not chosen one, leave any explicit -DCMAKE_BUILD_TYPE alone, and offer the four standard types to cmake-gui / ccmake.

Why

The project sets no build type and no optimisation flag anywhere, and neither docker/Dockerfile nor docker/Dockerfile.cpu passes one. An unset build type is not a neutral default: CMake then emits no -O flag at all, so every binary built from this repo, the released container images included, is compiled -O0.

That is measurable, not theoretical. Disassembling a shipped aarch64 binary, the per-frame input tensor normalisation in modules/models carried not one vector instruction, reloaded MEAN and STD from memory on every iteration, and issued a scalar fdiv per element:

ldr  s1, [x0]              ; src[i]
ldr  s0, [x0, x1, lsl #2]  ; MEAN[c]  -- reloaded every iteration
fsub s1, s1, s0
ldr  s0, [x0, x1, lsl #2]  ; STD[c]   -- reloaded every iteration
fdiv s0, s1, s0            ; a division, per element
str  s0, [x0]

objdump | grep -cE "\.4s|\.8h|\.16b" over that whole function returned 0.

Effect, measured

On an R-Car X5H (Cortex-A720), one clip, 198 inferred frames, same source built the same way apart from this commit:

input prep frame wall fps
as shipped (no build type, -O0) 33.8 ms 57.3 ms 17.5
with this commit (Release) 13.9 ms 37.0 ms 27.1

Per 1024x512 image, that one conversion goes from 14.4 ms to 6.4 ms, and it runs three times a frame. Nothing here is board-specific — the affected code is plain CPU work on the shared pipeline, so an x86_64 host running the CUDA or TensorRT provider was compiled -O0 too.

Why Release and not RelWithDebInfo

Deliberate, and the difference is not cosmetic. -O2 leaves that conversion completely unvectorised — measured 0 vector instructions in the loop at -O2, against a NEON ld3 de-interleaving loop at -O3. Only Release gets the win.

Risk

Release adds -DNDEBUG, which disables assert(). Checked before choosing it: there are no non-static_assert assert() calls anywhere under modules/ or app/, so nothing changes behaviourally.

Verification

Built docker/Dockerfile.cpu on this branch: the configure step reports Build type: Release, -O3 reaches the actual compile lines, the VisionPilot target links, and -DCMAKE_BUILD_TYPE=Debug is still respected.

Relation to the other two PRs

This is the first of three independent changes; the other two are opened alongside it and none of them depends on this one to build. Suggested review/merge order is this PR, then the input-tensor fusion, then the merged-graph NPU backend, because the later two are measured on top of a Release build.

Note on spell-check-differential

The check is red, and none of it comes from this branch. spell-check-differential scans every changed file in full, so it reports words that already live in those files on mainIpopt, libnice, CPACK, cipo, latc, Matx, dets, and the forbidden ROS2 among them. The same check has been failing on main in spell-check-daily every night for at least a week, and the last two merged PRs (#408, #411) merged red on it too. Every word this branch actually introduces is either already in the shared dictionary or added to .cspell.json here, verified locally with cspell against the repo config.

The project set no CMAKE_BUILD_TYPE and no optimisation flag anywhere, and
neither docker/Dockerfile nor docker/Dockerfile.cpu passes one. An unset
build type is not a neutral default -- CMake then emits no -O flag at all,
so every binary built from this repo, the released container images
included, was compiled -O0.

That is measurable, not theoretical. Disassembling a shipped aarch64
binary, the input tensor normalisation in modules/models carried not one
vector instruction, reloaded MEAN and STD from memory on every iteration
and issued a scalar fdiv per element. On a Cortex-A720 it cost 14.4 ms per
1024x512 image against 0.6 ms for the same source compiled -O3, and the
per-frame conversion runs that loop three times.

Default to Release when the user has not chosen, leave any explicit
-DCMAKE_BUILD_TYPE alone, and offer the four standard types to cmake-gui
and ccmake. Release rather than RelWithDebInfo is deliberate: -O2 leaves
that conversion completely unvectorised, and only -O3 turns it into the
NEON de-interleaving loop it should be.

Signed-off-by: Yutaka Kondo <yutaka.kondo@youtalk.jp>
@youtalk
youtalk force-pushed the fix/build-default-release branch from 696672c to 153d2d2 Compare September 10, 2026 00:14
@youtalk
youtalk marked this pull request as ready for review September 10, 2026 01:11

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant