Embedded · Benchmark na sprzęcie

GCC kontra Keil: open-source wygrywa na rozmiarze i szybkości.

Ten sam kod źródłowy — panel LED 64×64, FreeRTOS + CycloneTCP — zbudowany pięcioma wariantami toolchaina i zmierzony licznikiem cykli DWT bezpośrednio na STM32F429. Po tuningu bibliotek GCC 14.2 bije komercyjny Keil ARMCC w każdym teście. A cały eksperyment, od kodu po pomiar, wykonał agent AI.

Ostatnia aktualizacja:

Płytka STM32 połączona z matrycą LED 64×64 wyświetlającą wykres słupkowy porównania wydajności
3,75× szybciejGCC tuned: 51 ms vs 194 ms Keila (cały benchmark)
2,4× mniejszy firmware220 kB vs 537 kB ROM — ta sama funkcjonalność
0 zł licencjiGCC + newlib są w pełni open-source

01 / Wynik · Jeden wykres

Mapa efektywności: rozmiar × szybkość.

Każdy punkt to jeden kompletny firmware wgrany i zmierzony na płytce. Ideał — mały i szybki — leży w lewym dolnym rogu. Warianty Keila siedzą w prawej, „ciężkiej" części wykresu i nie schodzą poniżej 194 ms. GCC −O2 tuned łączy mały rozmiar z czasem niedostępnym dla Keila — dominuje wykres w sensie Pareto.

0100 200300 400 czas [ms] 0100 200300 400500 600 rozmiar ROM [kB] ◤ cel: mały i szybki GCC −O0 · 584 kB · 406 ms GCC −O2 · 210 kB · 327 ms Keil default · 537 kB · 194 ms Keil −O2+split · 510 kB · 194 ms GCC −O2 tuned · 220 kB · 51 ms

02 / Anatomia · Skąd ten czas

Z czego składa się każdy pasek.

Cykle CPU w podziale na trzy testy (wspólna skala, 100% = GCC −O0). W obu „fabrycznych" buildach GCC czas pożera segment MEM — bajtowe memcpy/memset z newlib-nano. Podmiana tych trzech funkcji (fast_libc.c) skraca pasek o ~40 mln cykli; u Keila analogiczny segment to wciąż 25 mln.

GCC −O0 0 ms
GCC −O2 0 ms
Keil default 0 ms
GCC −O2 tuned 0 ms

segmenty od lewej: INT (pełny kolor) · FLOAT (72%) · MEM (najjaśniejszy)

03 / Pamięć · W duchu urządzenia

Zajętość flasha jako matryca LED.

Każda dioda to 16 kB z 2 MB flasha STM32F429 — wizualizacja jak na panelu, którym steruje ten firmware. GCC −O2 zapala 13 z 128 diod; Keil potrzebuje ich prawie trzykrotnie więcej. Wolna przestrzeń to miejsce na przyszłe animacje, fonty i bufory.

04 / Dane · Bez skrótów

Pełne wyniki pomiarowe.

Test Keil default Keil −O2+split GCC −O0 GCC −O2 GCC −O2 tuned Najlepszy
ROM (kod + dane)536,7 kB509,7 kB584,2 kB210,2 kB219,7 kBGCC · 2,4×
INT — pętla LCG, 200 tys. iteracji19 ms19 ms83 ms14 ms5 mstuned · 3,35×
FLOAT — sinf() na FPU, 20 tys. iteracji24 ms26 ms49 ms40 ms14 mstuned · 1,73×
MEM — memset+memcpy, 500 × 4 kB149 ms148 ms273 ms273 ms31 mstuned · 4,70×
RAZEM194 ms194 ms406 ms327 ms51 mstuned · 3,75×
Metodologia i uczciwość porównania (rozwiń)

Warianty. Keil MDK 5.37 (ARMCC 5.06u7): „default" to domyślna optymalizacja armcc (≈−O2 — jawne ustawienie −O2 nie zmieniło czasów, zmniejszyło tylko ROM przez split sections). GCC: Arm GNU Toolchain 14.2.Rel1, newlib-nano, linker script z SW4STM32.

Wariant „tuned" = GCC −O2 + trzy zmiany: (a) własne słowo-po-słowie memcpy/memset i wielomianowy sinf (fast_libc.c — nadpisują bajtowe wersje newlib-nano przy linkowaniu), (b) -ffast-math -funroll-loops (główny zysk w INT), (c) prefetch flasha (FLASH_ACR_PRFTEN).

Uczciwość porównania. Prefetch włączono w kodzie wspólnym i Keil został z nim przebudowany i zmierzony ponownie — wynik identyczny co do ~0,001% (pętle mieszczą się w I-cache ART). Ta sama technika fast_libc.c dołączona do projektu Keila poprawiłaby i jego wynik — ale kompilator open-source już teraz robi to samo zadanie szybciej, mniejszym binarium i za darmo.

Weryfikacja. Każdy wariant flashowany na płytkę i sprawdzony: baner SWO (toolchain + wyniki DWT), animacja scrollującego tekstu na kamerze RTSP, ping i panel HTTP. Pomiar: DWT→CYCCNT @ 168 MHz, jednorazowo po starcie, sekcja krytyczna bez sieci.

05 / Puenta · Jak to zmierzono

Cały eksperyment wykonał agent AI — na prawdziwym sprzęcie.

Laptop z terminalem agenta AI obok matrycy LED 64×64 wyświetlającej padający śnieg — kadr jak z filmu „Od promptu do pikseli

Cały eksperyment — dopisanie benchmarku do firmware, pięć kompilacji dwoma toolchainami, flashowanie, pomiary na sprzęcie i weryfikacja obrazu na fizycznym panelu LED — wykonał agent AI, sterując narzędziami z linii poleceń. Dokładnie ten sam zestaw i ta sama pętla, które widzisz w naszym filmie „Od promptu do pikseli".

Keil z agentem: szybciej niż człowiek z Keilem

Agentowe programowanie embedded działa też na komercyjnym stacku. Keil ma CLI (UV4.exe -r), STM32CubeProgrammer flashuje i czyta SWO z konsoli — agent w pętli edytuje kod, buduje, wgrywa i czyta logi ITM szybciej, niż człowiek zdąży przeklikać się przez µVision. Każda iteracja „zmiana → build → flash → dowód w SWO" zamykała się w ~2 minuty, a numer buildu w banerze startowym dawał twardy dowód, że na płytce działa właściwy firmware.

Ale prawdziwa dźwignia to open source

Keil w tej pętli pozostaje wąskim gardłem: zamknięty kompilator bez wglądu w biblioteki, licencja per stanowisko, tylko Windows. Agent może go obsługiwać, ale nie może z nim współpracować. Z narzędziami open-source pętla domyka się w całości:

  • arm-none-eabi-gcc — kompilator, którego flagi, biblioteki i wygenerowany kod agent może inspekcjonować i stroić; efekt: firmware 3,75× szybszy i 2,4× mniejszy od Keila;
  • newlib / newlib-nano — gdy memcpy okazał się bajtowy, agent to zobaczył w źródle i napisał zamiennik, zamiast zgadywać, co robi czarna skrzynka;
  • GNU make + skrypty shell — build deterministyczny i tekstowy, idealny interfejs dla agenta (i dla CI);
  • OpenOCD + st-flash + GDB — flashowanie i pełny debug source-level bez licencji, na Windows, Linuksie i macOS;
  • DWT/ITM (SWO) — benchmark z tego raportu to 60 linii C i printf przez SWO, zero dodatkowego sprzętu;
  • ffmpeg + kamera RTSP — agent „patrzy" na fizyczny panel i sam potwierdza, że animacja scrolluje bez artefaktów;
  • git — każdy krok eksperymentu zapisany atomowym commitem: wynik odtwarzalny i audytowalny.
Zamknięte IDE ogranicza agenta do roli klikacza. Otwarty toolchain robi z niego inżyniera: może przeczytać źródło biblioteki, zmierzyć skutek na sprzęcie i poprawić wynik — w jednej, samodzielnej pętli.

Co z tego wynika

Po pierwsze: agent + dowolny toolchain z CLI bije ręczną pracę w IDE, bo iteracja jest tania i weryfikowalna. Po drugie: agent + open source bije agenta z narzędziami zamkniętymi, bo przewaga agenta rośnie z przezroczystością stosu. Po trzecie: koszt wejścia to zero złotych i jeden plik build.sh — cała reszta to sprzęt, który już leży na biurku.

Pomiar: 16.07.2026 · DWT→CYCCNT @ 168 MHz · Keil MDK 5.37 (ARMCC 5.06u7) · Arm GNU Toolchain 14.2.Rel1 · weryfikacja: SWO + kamera RTSP + HTTP

Wdrożenie u Was

Chcesz taką pętlę w swoim zespole embedded?

Wdrażamy agentów AI, które budują, wgrywają i weryfikują firmware na Waszym sprzęcie — z pomiarem zamiast obietnic. 30 minut wystarczy, żeby sprawdzić, czy ma to u Was sens.