Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
Start with -O2, an explicit minimum CPU target, and measurements on the real device. Move to -Os/-Oz, -O3, LTO, PGO, or relaxed floating-point rules only when a controlled test proves they improve the resource that actually limits your product. There is no universal “best” GCC or Clang flag set: an application, kernel, shared library, and complete image have different constraints.
Define the bottleneck before changing flags
“Optimization” may mean lower latency, higher throughput, smaller resident memory, less flash, faster boot, lower energy, or tighter worst-case timing. Record the metric and its acceptance limit first.
- CPU: wall-clock latency, throughput, cycles, instructions, branch and cache misses, CPU utilization, system calls and context switches.
- Memory: peak and resident memory, heap-allocation rate, stack use, page faults, DMA/CMA pressure, and shared versus private pages.
- Storage: ELF size, stripped size, compressed and uncompressed filesystem size, kernel/modules, symbols and relocations.
- Energy and real time: energy per operation, thermal throttling, jitter, interrupt response and worst-case latency—not only averages.
A smaller image can require more decompression CPU; a faster build can consume more energy; and a throughput gain can worsen instruction-cache behavior or tail latency.
Freeze a reproducible baseline
Capture the toolchain and target before experimenting:
#1 Best Overall
- Featuring a 1GHz processor and SGX530 Graphics Engine.
- IntegratedNEON SIMD coprocessor;
- On board eMMC memory
- This development board offer high-speed USBconnectivity, an HDMIcompatible interface, and expandable memory option.
- Advanced for BeagleBone Black AM335x CortexA8 Development Board
gcc --version
clang --version
ld --version
ld.lld --version
gcc -dumpmachine
gcc -Q --help=target
gcc -Q -O2 --help=optimizers
clang --target=aarch64-linux-gnu -### -c test.c
Also record the target triple, CPU revision and extensions, ABI and floating-point ABI, glibc or musl version, sysroot, binutils/LLVM utilities, linker, kernel configuration, build-system version and release configuration. Clang’s -### output shows the commands its driver would invoke, helping reveal the assembler, linker, runtime and implicit target options (Clang command guide).
Keep the exact commands visible with make V=1, ninja -v, or:
cmake -S . -B build -DCMAKE_BUILD_TYPE=RelWithDebInfo
-DCMAKE_C_FLAGS="-O2 -g" -DCMAKE_CXX_FLAGS="-O2 -g"
cmake --build build --verbose
Choose the CPU baseline deliberately
-march selects instructions the binary may use; -mtune primarily tunes scheduling and choices while retaining the selected ISA; -mcpu commonly combines both (the exact behavior is target-specific). GCC documents these choices for ARM, AArch64 and RISC-V.
Free tools Windows power users keep installed
One-click scans. No signup required.
# AArch64 portable baseline plus tuning
aarch64-linux-gnu-gcc -O2 -march=armv8-a -mtune=cortex-a53 ...
# Product tied to one known CPU
aarch64-linux-gnu-gcc -O2 -mcpu=cortex-a72 ...
# 32-bit ARM: verify ABI and FPU for the board
arm-linux-gnueabihf-gcc -O2 -mcpu=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard ...
# RISC-V: treat ISA and ABI as a pair
gcc -O2 -march=rv64gc -mabi=lp64d ...
Do not leak -march=native into a cross build. It describes the build host, not necessarily the device, and can produce illegal-instruction crashes; GCC explicitly documents host-feature selection for AArch64. For multiple boards, define the oldest supported ISA and ship separately named hardware-specific images when justified. Check NEON/SVE or RISC-V vector availability, endianness, PIE/PIC, atomics, C++ ABI and hard- versus soft-float compatibility.
Rank #2
Optimization levels: what to test
GCC’s optimization documentation describes trade-offs among speed, size, compile time and debuggability; an optimization level never guarantees a speedup. Clang offers familiar levels, but equal-looking options do not imply equal passes or machine code (Clang guide).
| Level | Use | Cautions |
|---|---|---|
-O0 |
Initial debugging and tiny diagnostics | Timing, races and generated code differ greatly from release builds. |
-Og |
Debuggable development that remains somewhat representative | Still not a production performance result. |
-O2 |
Default production baseline | Measure against your workload. |
-O3 |
Selected hot components | May increase code size, register pressure, I-cache misses and build time. |
-Os/-Oz |
Measured size constraint; Clang’s -Oz is more size-focused |
Less inlining can reduce speed, though cache effects can occasionally help. |
-Ofast |
Specialized numerical code | Can relax floating-point and language assumptions; never a blanket release preset. |
Useful starting configurations are -O2 -g for a symbol-bearing build and -O2 for deployment. Keep symbols externally and strip the artifact only after confirming unwind and crash-reporting needs:
aarch64-linux-gnu-strip --strip-unneeded app
Keep strict floating-point semantics globally. Isolate and review -ffast-math, -funsafe-math-optimizations or -fno-math-errno only after testing NaN, infinity, signed zero, rounding, exceptions and convergence boundaries.
Reduce image size beyond an optimization level
-fdata-sections -ffunction-sections
-Wl,--gc-sections
Section garbage collection, feature removal at configuration time, carefully chosen shared libraries, external debug symbols and linker-map inspection often matter more than switching from -O2 to -Os. Inspect with:
Rank #3
- There are several options for this item, this option is with header. Please click the image 2 to check the package content.
- Luckfox Lyra is a cost-effective Linux micro development board based on the Rockchip RK3506G2 to provide a simple and efficient development platform. Onboard multiple high-speed interfaces including MIPI DSl, RMll, USB, etc. to meet various application scenarios.
- The low-speed interfaces utilize Rockchip Matrix l0 design which supports multiplexing 98 function siqnals on GPlO pins, and can freely combine PWM, UART, 12C, SPl, and l2S for quick development and debugging.
- Tripe-core ARM Cortex-A7 32-bit core, with integrated VFP to support single- and double-precision floating-point operations. Built-in ARM Cortex-M0 MCU design, supports SMP and AMP configuration. Built-in 128MB DDRL3 for multi-core applications
- The low-speed interfaces adopt Rockchip Matrix IO design, which allows rich function signals to share the limited chip pins, making peripheral circuit adaptation more flexible. Built-in audio and video codec, supports multiple audio inputs and outputs, providing high-quality audio playback and recording functions
size app
readelf -S app
readelf -Ws app
nm -S --size-sort app | tail
Garbage collection can remove indirectly referenced registration tables, constructors or plugin entry points. Add appropriate linker-script KEEP() rules and startup tests rather than assuming every referenced symbol is visible to the linker.
LTO: powerful, but a build-system feature
GCC:
gcc -O2 -flto -c a.c
gcc -O2 -flto -c b.c
gcc -O2 -flto a.o b.o -o app
Clang supports full and scalable ThinLTO:
clang -O2 -flto=full ...
clang -O2 -flto=thin ...
See Clang ThinLTO documentation. LTO can enable cross-module inlining, constant propagation and dead-code elimination, but increases link memory and complexity. GCC notes that linker-plugin-aware archive tools such as ar, nm and ranlib may be required (GCC options); Clang LTO is natively supported by ld.lld and can use a gold plugin (Clang toolchain). Binary-only objects, inline assembly, mixed compiler versions and linker scripts are common failure points. Keep a non-LTO fallback and use -fno-lto for an isolated component when necessary.
PGO is a workload process, not a magic switch
For Clang’s instrumentation flow:
clang -O2 -fprofile-instr-generate -fcoverage-mapping source.c -o app-instrumented
LLVM_PROFILE_FILE="app-%p.profraw" ./app-instrumented
llvm-profdata merge -output=app.profdata app-*.profraw
clang -O2 -fprofile-instr-use=app.profdata source.c -o app-pgo
Use representative hardware and traffic, include error and recovery paths, then validate trained and untrained workloads. Profiles become stale after significant source, compiler or workload changes. LLVM’s PGO guide covers the workflow. Advanced kernel workflows such as AutoFDO, ThinLTO and Propeller have their own requirements; the documented kernel Propeller workflow requires LLVM 19 or later (kernel documentation).
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Fix the driver behind crashes, sound loss and screen glitches3Repair Windows errors before they cause bigger problemsGCC versus Clang/LLVM
GCC is often the lowest-risk choice for vendor BSPs, GNU extensions and broad architecture support. Clang/LLVM offers integrated tools, ThinLTO, sanitizers, ld.lld, llvm-ar and strong analysis workflows. Clang is not a complete environment by itself: compiler runtime, C library, C++ ABI, startup objects, assembler, linker and sysroot must agree (toolchain components). Compare matched versions, target, linker, libraries, flags and workloads; do not claim a universal speed winner.
Rank #4
- ZYNQ-7000 ARM+FPGA SoC: Powered by Xilinx ZYNQ XC7Z010/020 with dual-core ARM Cortex-A9 and programmable logic—ideal for embedded and FPGA development.
- Integrated Interfaces for Versatile Applications: Features HDMI, USB 2.0 Host, UART, JTAG, Gigabit Ethernet (PS & PL), SD card, and 40-pin expansion for AD/DA, LCD, and camera modules.
- Robust Memory & Storage: Equipped with 512MB/1GB DDR3, 128Mb QSPI Flash, 64Kbit EEPROM, and boot selection via JTAG/QSPI/SD for flexible design setups.
- Industrial-Grade Design: Compact 90x60mm board with immersion gold finish, suitable for industrial environments. 5V/1A power input supports stable operation.
- Support for Linux and Hardware Demos: Supports embedded Linux system, MIPI CSI camera input (7020 only), and comes with HDL demos—perfect for research and education.
Kernel builds with LLVM
The Linux kernel supports LLVM-based builds:
make LLVM=1 defconfig
make LLVM=1 -j"$(nproc)"
Or specify tools explicitly:
make CC=clang LD=ld.lld AR=llvm-ar NM=llvm-nm STRIP=llvm-strip
LLVM=1 selects LLVM utilities, while cross compilation uses a target triple rather than simply prefixing a GNU compiler name. Architecture, kernel version, external modules, assembler and vendor drivers can change the required command. Consult the kernel LLVM build documentation.
Keep build purposes separate
debug: -Og -g3 -fno-omit-frame-pointer
release-debuggable:-O2 -g -fno-omit-frame-pointer
release: -O2 (or measured alternative), symbols archived
size: -Os or -Oz plus section GC
sanitized: -O1 or -O2 -g with target-supported runtime
Clang sanitizers generally require flags at compile and link time. For example:
clang -O1 -g -fsanitize=address,undefined
-fno-omit-frame-pointer app.c -o app-sanitize
AddressSanitizer, UBSan, ThreadSanitizer, CFI and related tools can add substantial size and timing overhead; not all combinations or target runtimes are supported. Trap-style sanitizer operation can suit constrained systems (Clang User’s Manual). Never report sanitized measurements as production performance.
A disciplined experiment loop
- Baseline: freeze source, toolchain, sysroot, kernel, frequency governor and workload.
- Measure: use
/usr/bin/time -v,perf stat,perf record -g,perf reportandstrace -cwhere target support permits. Include cold/warm startup, RSS, page faults, image size and energy. - Change one variable:
-O2→ target selection →-Os/-Oz→ selected-O3→ section GC → LTO → PGO. - Validate: unit, integration, hardware-in-loop, soak, thermal, watchdog, power-cycle, network/storage fault and upgrade/rollback tests.
- Inspect:
file,readelf -h -A -d,lddin a compatible environment,size, hardening properties and disassembly. Test the oldest supported board. - Retain: archive flags, versions, profile workload, benchmark data, artifact hashes and a reproducible rollback build.
Common failures and recovery
-O3is slower: check I-cache misses, branch behavior, inlining and register pressure; return to-O2or limit-O3to hot units.- Illegal instruction: remove host-native options, inspect attributes/disassembly and rebuild for the minimum ISA.
- LTO link failure: verify plugin-aware tools and consistent compiler versions; disable LTO for the offending library.
- PGO regression: collect multiple representative profiles, include rare paths and define profile invalidation rules.
- Sanitized image will not start: provide the matching runtime, reduce sanitizers, use a development target or trap mode.
- Size optimization breaks startup: inspect the map, restore retained sections and test constructors/plugins.
- Clang fails where GCC works: isolate GCC extensions, inline assembly, runtime, assembler, linker or vendor patches before deciding whether to change source or compiler.
Practical policy
For most products, adopt -O2 with an explicit minimum ISA and ABI as the reproducible baseline. Use -Os/-Oz for measured image constraints, LTO for components that can absorb its build cost, and PGO only with stable representative workloads. Treat -O3, -Ofast, fast math, AutoFDO and layout tools as reviewed experiments. Benchmark on target hardware, preserve symbols outside the deployed image, and keep the baseline build as rollback insurance.
Open-source GCC or Clang is usually sufficient. Consider a commercial Arm compiler or development suite only when vendor support, qualification evidence, traceability, diagnostics or integrated profiling has measurable business value; do not buy a toolchain simply because a flag sounds more aggressive.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

