Embedded · Benchmark na sprzęcie

Kompilator za 7 565 zł rocznie właśnie przegrał z darmowym. Na prawdziwym sprzęcie, w każdym teście.

Ten sam kod źródłowy (panel LED 64×64, FreeRTOS + CycloneTCP) zbudowany pięcioma wariantami toolchaina i zmierzony licznikiem cykli bezpośrednio na STM32F429. Cały eksperyment, od kodu przez kompilacje po pomiar i weryfikację na fizycznym panelu, wykonał agent AI.

Autor: · Ostatnia aktualizacja:

3,75× szybciej GCC tuned: 51 ms vs 194 ms Keila (cały benchmark)
2,4× mniejszy firmware 220 kB vs 537 kB ROM, ta sama funkcjonalność
0 zł licencji ~113 tys. zł zostaje w budżecie 5-os. zespołu przez 3 lata

„Na produkcję bierzemy komercyjny toolchain. Open source to ryzyko.”

Za to zdanie płaci się dwa razy: raz w licencjach (7 565 zł netto rocznie za stanowisko Keil MDK Professional), drugi raz w przekonaniu, że w zamian dostaje się szybszy i mniejszy firmware. Pierwszą pozycję widać na fakturze. Drugą postanowiliśmy po prostu zmierzyć, nie na syntetycznym benchmarku z ulotki, tylko na kompletnym, produkcyjnym firmware z RTOS-em i stosem sieciowym, wgranym na prawdziwą płytkę.

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

Trzy funkcje, których nikt nie podejrzewa.

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 406 ms
GCC −O2 327 ms
Keil default 194 ms
GCC −O2 tuned 51 ms

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

Zajętość pamięci flash.

Każdy punkt to 16 kB z 2 MB flasha STM32F429. Firmware z GCC −O2 zajmuje 13 ze 128 bloków; Keil potrzebuje ich prawie trzykrotnie więcej. Wolna przestrzeń to realny zapas na rozwój produktu: kolejne funkcje, fonty, bufory.

GCC −O0 584 kB
Keil default 537 kB
Keil −O2+split 510 kB
GCC −O2 tuned 220 kB
GCC −O2 210 kB

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.

Ile kosztuje ta różnica w licencjach.

Benchmark wyżej pokazuje, że open source jest szybszy i mniejszy. Cennik dopowiada resztę: Keil MDK jest dziś sprzedawany wyłącznie w subskrypcji per stanowisko, a Arm GNU Toolchain (ten sam, który wygrał ten benchmark) jest bezpłatny również w projektach komercyjnych.

Keil MDK v6 Professional 7 565 zł netto / rok / stanowisko, oficjalny sklep Arm (lipiec 2026)
Keil MDK v6 Essential 3 780 zł netto / rok / stanowisko; u dystrybutorów bywa ~15% drożej
Arm GNU Toolchain (GCC) 0 zł bez opłat i bez limitu użycia komercyjnego

Zespół 5 inżynierów, horyzont 3 lat: same licencje toolchaina (PLN netto)

MDK v6 Professional 113 tys. zł
MDK v6 Essential 57 tys. zł
Arm GNU Toolchain 0 zł
LicencjaModelCena katalogowaW PLN nettoStatus
MDK v6 Communitysubskrypcja0 $0 złtylko projekty niekomercyjne
MDK v6 Essentialsubskrypcja / rok / stanowisko999 $ / rok3 780 zł / rokw sprzedaży
MDK v6 Professionalsubskrypcja / rok / stanowisko1 999 $ / rok7 565 zł / rokw sprzedaży
MDK v5 Essentialwieczysta node-locked + 20% / rok maintenance3 840 $≈14 600 złwycofana, sprzedaż do 30.06.2025
MDK v5 Pluswieczysta node-locked + 20% / rok maintenance6 600 $≈25 100 złwycofana
MDK v5 Professionalwieczysta node-locked (floating ~20% drożej)9 500 $≈36 100 złwycofana
Arm GNU Toolchain (GCC)open source: Twój firmware na dowolnej licencji0 $0 złbez ograniczeń komercyjnych
Źródła i założenia cen (rozwiń)

Subskrypcje MDK v6: oficjalny sklep Arm (store.arm.com), ceny wyświetlane w PLN netto, stan: lipiec 2026 (katalogowo 999 $ Essential i 1 999 $ Professional rocznie). Subskrypcja 3-letnia ok. 20% taniej; u dystrybutorów (np. DigiKey) bywa ok. 15% drożej. Darmowa edycja Community obejmuje wyłącznie projekty niekomercyjne.

Licencje wieczyste MDK v5 (już niedostępne): ceny wg archiwalnych cenników dystrybutorów Keil (USD; zbieżne z archiwalnym sklepem Arm), przeliczone po ~3,8 zł/USD. Arm zakończył ich sprzedaż 30 czerwca 2025, a odnowienia maintenance przyjmował tylko do 30 czerwca 2026. Maintenance kosztował 20% ceny licencji rocznie (40% przy wznowieniu po przerwie); pierwszy rok był wliczony.

Wykres „5 inżynierów × 3 lata”: licencje node-locked per stanowisko, ceny bieżące ze sklepu Arm (5 × 3 × 7 565 zł ≈ 113 tys. zł; 5 × 3 × 3 780 zł ≈ 57 tys. zł), bez rabatów wolumenowych i bez kosztów administracji licencjami.

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

Dopisanie benchmarku do firmware, pięć kompilacji dwoma toolchainami, flashowanie, pomiary na sprzęcie i weryfikacja obrazu na fizycznym panelu LED — agent zrobił to wszystko sam, sterując narzędziami z linii poleceń.

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ć (tak powstał zwycięski wariant „tuned”);
  • 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: trzy oszczędności naraz

  • Czas inżyniera: najdroższa pozycja każdego projektu firmware. Agent domyka pętlę „zmiana → build → flash → dowód na sprzęcie” w ~2 minuty i powtarza ją bez znużenia. Inżynier przestaje czekać i klikać, a zaczyna decydować. Ta sama liczba etatów domyka więcej tematów w tygodniu, a eksperymenty odkładane „na kiedyś” (jak ten benchmark) po prostu się dzieją.
  • Licencje: 0 zł. Cała pętla (kompilator, debug, flashowanie) działa na open source. W 5-osobowym zespole to ~113 tys. zł zostające w budżecie co 3 lata (rachunek wyżej).
  • Zapas na sprzęcie. Firmware 2,4× mniejszy i 3,75× szybszy to nowe funkcje bez przesiadki na droższy mikrokontroler, a przy większych seriach często tańszy układ w BOM.

Do startu nie potrzeba nic, czego już nie macie: toolchain jest darmowy, płytka leży na biurku, a jak wdrażamy takie pętle w zespołach, opisujemy na stronie AI dla embedded.

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

Policzmy ten sam rachunek na Waszym firmware.

Bierzemy jeden Wasz projekt, uruchamiamy agentową pętlę build → flash → pomiar na Waszym sprzęcie i pokazujemy liczby: czas iteracji, rozmiar binarki, koszt licencji. Krótka rozmowa wystarczy, żeby ustalić, od czego zacząć. Bez zobowiązań.