Benchmarks
Every figure below is measured on real hardware with the project's own benchmark suite. Compiler options are the highest optimization level, optimized for time (GCC at -O3 with LTO when available, Keil and IAR at their highest settings).
All timing columns are CPU clock cycles, average case. The worst case (WCET) for each primitive on each chip is published in the test headers under Include/Test/Chip/ — in a real-time system that is the number that matters.
At a glance
Practical ports
These are the ports used in day-to-day embedded work, from 8-bit AVR to Cortex-M55 and RISC-V. ... repeats the chip, platform and toolchain of the row above.
| Chipname | Platform | Build | Yield | Sem | FIFO | Msgq | Bmq | Mail/I | Sem/I | Msgq/I | Bmq/I | Mem | Alrm | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ATMEGA328P | AVR | GCC | 408 | 719 | 686 | 313 | 1065 | 1318 | 624 | 626 | 905 | 1073 | N/A | TBD |
| ATMEGA1284P | ... | ... | 437 | 751 | 717 | 314 | 1098 | 1352 | 637 | 639 | 921 | 1087 | 1680 | TBD |
| ATMEGA2560 | ... | ... | 449 | 774 | 736 | 326 | 1131 | 1396 | 656 | 654 | 942 | 1117 | 1686 | TBD |
| R5F104PJ | RL78 | CCRL | 261 | 565 | 520 | 308 | 924 | 1225 | 539 | 500 | 789 | 964 | 1854 | TBD |
| PIC24FJ128 | PIC24F | XC16 | 152 | 334 | 271 | 168 | 468 | 654 | 274 | 213 | 352 | 461 | 379 | TBD |
| DSPIC33EP512 | DSPIC33E | ... | 214 | 447 | 353 | 219 | 608 | 851 | 368 | 278 | 455 | 602 | 448 | TBD |
| MSP430F149 | MSP430 | CCS | 312 | 641 | 573 | 312 | 985 | 1278 | 528 | 487 | 739 | 898 | N/A | TBD |
| MSP430FR5994 | MSP430X | ... | 468 | 1054 | 891 | 492 | 1573 | 2072 | 891 | 784 | 1176 | 1464 | 3291 | TBD |
| STM32F030F4 | Cortex-M0 | Keil | 362 | 763 | 666 | 379 | 1196 | 1609 | 689 | 616 | 950 | 1211 | N/A | TBD |
| ... | ... | GCC | 366 | 802 | 690 | 396 | 1246 | 1685 | 705 | 622 | 954 | 1200 | N/A | TBD |
| HC32L136K8 | Cortex-M0+ | Keil | 211 | 422 | 370 | 219 | 646 | 873 | 403 | 350 | 532 | 673 | 542 | TBD |
| STM32L071CB | Cortex-M0+ | Keil | 335 | 581 | 532 | 253 | 892 | 1167 | 554 | 524 | 756 | 945 | N/A | TBD |
| ... | ... | GCC | 337 | 656 | 600 | 284 | 947 | 1260 | 578 | 602 | 794 | 1003 | N/A | TBD |
| STM32G071RB | Cortex-M0+ | Keil | 264 | 465 | 407 | 209 | 697 | 948 | 463 | 400 | 577 | 726 | N/A | 904 |
| ... | ... | GCC | 289 | 536 | 480 | 233 | 694 | 958 | 489 | 462 | 599 | 772 | N/A | 892 |
| ... | ... | IAR | 298 | 545 | 480 | 252 | 762 | 1012 | 532 | 471 | 643 | 757 | N/A | 1062 |
| STM32F103RE | Cortex-M3 | Keil | 203 | 438 | 385 | 226 | 684 | 930 | 392 | 354 | 542 | 707 | 518 | TBD |
| ... | ... | GCC | TBD | TBD | TBD | TBD | TBD | TBD | TBD | TBD | TBD | TBD | TBD | TBD |
| STM32F405RG | Cortex-M4F | Keil | 180 | 345 | 321 | 180 | 667 | 886 | 309 | 302 | 498 | 626 | 455 | TBD |
| ... | ... | GCC | 196 | 388 | 345 | 192 | 677 | 953 | 381 | 349 | 566 | 743 | 411 | TBD |
| STM32F429ZI | Cortex-M4F | Keil | 168 | 309 | 285 | 176 | 608 | 800 | 349 | 277 | 429 | 586 | 393 | 666 |
| ... | ... | GCC | 172 | 352 | 293 | 176 | 478 | 769 | 357 | 313 | 474 | 631 | 384 | 620 |
| ... | ... | IAR | 160 | 345 | 292 | 188 | 574 | 776 | 354 | 277 | 502 | 610 | 416 | 775 |
| STM32F767IG | Cortex-M7F | Keil | 176 | 329 | 277 | 174 | 510 | 694 | 328 | 259 | 413 | 516 | 334 | TBD |
| ... | ... | GCC | 182 | 335 | 288 | 156 | 473 | 643 | 313 | 264 | 375 | 514 | 332 | TBD |
| STM32H743ZI | Cortex-M7F | Keil | 144 | 288 | 220 | 149 | 421 | 626 | 252 | 216 | 327 | 444 | 295 | 549 |
| ... | ... | GCC | 164 | 308 | 254 | 152 | 429 | 585 | 300 | 242 | 344 | 456 | 295 | 479 |
| ... | ... | IAR | 176 | 308 | 264 | 148 | 524 | 718 | 284 | 274 | 396 | 521 | 297 | 535 |
| M2351KIAAE | Cortex-M23 | Keil | 213 | 390 | 349 | 197 | 675 | 957 | 441 | 339 | 535 | 655 | 498 | 777 |
| ... | ... | GCC | 265 | 554 | 538 | 210 | 706 | 1008 | 492 | 444 | 565 | 751 | 674 | 763 |
| ... | ... | IAR | 228 | 512 | 387 | 211 | 642 | 887 | 444 | 366 | 522 | 663 | 501 | 900 |
| STM32N657X0 | Cortex-M55 | GCC | 163 | 298 | 252 | 135 | 391 | 524 | 289 | 256 | 336 | 427 | 307 | 527 |
| ... | ... | Keil | 155 | 281 | 228 | 130 | 421 | 571 | 282 | 246 | 364 | 454 | 309 | 555 |
| ... | ... | IAR | 162 | 303 | 262 | 154 | 456 | 607 | 290 | 260 | 375 | 449 | 330 | 631 |
| TMS570LS0432 | Cortex-R4 | CCS | 306 | 493 | 460 | 193 | 686 | 897 | 480 | 464 | 592 | 736 | 533 | TBD |
| TMS570LC4357 | Cortex-R5 | ... | 275 | 479 | 467 | 216 | 746 | 998 | 440 | 435 | 595 | 763 | 482 | TBD |
| TMS320F2812 | C28x | CCS | 217 | 493 | 407 | 229 | 706 | 954 | 436 | 381 | 583 | 727 | 939 | TBD |
| TMS320F28335 | C28x/FPU32 | ... | 246 | 513 | 440 | 235 | 751 | 1001 | 440 | 413 | 622 | 770 | 946 | TBD |
| CH32V307VC | RV32IMAC | GCC | 209 | 386 | 336 | 172 | 538 | 698 | 350 | 306 | 436 | 555 | 433 | TBD |
| ... | RV32IMAFC | ... | 217 | 398 | 341 | 172 | 557 | 705 | 358 | 307 | 444 | 556 | 433 | TBD |
| Xeon 6326 | X86-LINUX | GCC | 24k | 24k | 24k | 46 | 24k | 24k | 31k | 30k | 34k | 53k | 159 | TBD |
The smallest port
The minimal proof-of-concept that finishes the benchmark runs on an ATmega328P — 32 KB flash and 2 KB SRAM. On the STM32F030F4, the absolute minimum kernel is 1.6 KB of ROM and 432 bytes of RAM, including the first thread's control block and stack and the 64-byte interrupt stack. The kernel plus stripped HAL alone is 52 bytes.
Commemorative ports
Ports to machines that shaped computing, kept alive for the challenge — and because they prove the abstraction is not tied to a modern instruction set.
| Chipname | Platform | Build | Yield | Sem | FIFO | Msgq | Bmq | Mail/I | Sem/I | Msgq/I | Bmq/I | Mem | Alrm | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| RP2A03/FC-84 | MOS6502 | CC65 | 4073 | 5435 | 5435 | 2028 | 7726 | 10445 | 4831 | 5180 | 7220 | 8350 | 7484 | TBD |
| .../MESEN | ... | ... | 4060 | 5439 | 5424 | 2040 | 7728 | 10443 | 4836 | 5185 | 7227 | 8355 | 7446 | TBD |
| SPCE061A | unSP | GCC | 694 | 1732 | 1548 | 927 | 2671 | 3709 | 1619 | 1475 | 2242 | 2889 | 3518 | TBD |
| PIC32MZ2048 | MIPS | XC32 | 190 | 345 | 305 | 150 | 475 | 620 | 295 | 260 | 370 | 465 | 365 | TBD |
| ... | MIPS-FR64 | ... | 475 | 630 | 585 | 160 | 775 | 935 | 400 | 360 | 490 | 585 | 371 | TBD |
| Z84C0004/TP-801 | Z80 | Z88DK | TBD | TBD | TBD | TBD | TBD | TBD | TBD | TBD | TBD | TBD | TBD | TBD |
RVM virtualized ports
The same kernel running as an unprivileged virtual machine on RVM. V is the virtualization overhead on normal operations, V/I the overhead on interrupt operations.
| Chipname | Platform | Build | Yield | Sem | FIFO | Msgq | Bmq | V | Mail/I | Sem/I | Msgq/I | Bmq/I | V/I | Mem | Alrm | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| STM32L071CB | Cortex-M0+ | Keil | 382 | 701 | 609 | 302 | 1007 | 1347 | 14% | 1370 | 1292 | 1545 | 1741 | 147% | N/A | 1216 |
| ... | ... | GCC | 400 | 751 | 649 | 321 | 1064 | 1420 | 19% | 1424 | 1341 | 1603 | 1796 | 210% | N/A | 1291 |
| STM32F405RG | Cortex-M4F | Keil | 252 | 436 | 372 | 200 | 708 | 924 | 40% | 1180 | 1088 | 1288 | 1452 | 281% | 385 | 798 |
| ... | ... | GCC | 312 | 540 | 448 | 204 | 656 | 1008 | 59% | 1336 | 1252 | 1404 | 1572 | 250% | 380 | 739 |
| STM32F767IG | Cortex-M7F | Keil | 184 | 293 | 275 | 144 | 504 | 705 | 6% | 772 | 742 | 899 | 983 | 135% | 275 | 578 |
| ... | ... | GCC | 192 | 352 | 292 | 148 | 466 | 650 | 6% | 903 | 853 | 1001 | 1119 | 239% | 270 | 508 |
| CH32V307VC | RV32IMAC | GCC | 233 | 384 | 336 | 148 | 489 | 629 | 17% | 1287 | 1239 | 1340 | 1421 | 267% | 390 | 605 |
| ... | RV32IMAFC | ... | 325 | 497 | 436 | 169 | 616 | 767 | 50% | 1789 | 1742 | 1857 | 1951 | 399% | 390 | 608 |
Even at the worst case in this table, a virtualized context switch is still around 25× faster than RT-Linux on a comparable Cortex-M7 — and the overhead is bounded, not just small on average.
Metric definitions
| Metric | Meaning |
|---|---|
| Yield | Yield from one thread to another |
| Mailbox communication between two threads | |
| Sem | Semaphore communication between two threads |
| FIFO | FIFO read/write pair within a single thread |
| Msgq | Message queue between two threads (only the receiver may block) |
| Bmq | Blocking message queue (both sides may block) |
| Mail/I | Send to a mailbox from an interrupt |
| Sem/I | Post to a semaphore from an interrupt |
| Msgq/I | Send to a message queue from an interrupt |
| Bmq/I | Send to a blocking message queue from an interrupt |
| Mem | A pair of memory-pool malloc/free calls |
| Alrm | Average processing time of five periodic alarms (1/2/3/5/7 ticks) |
Reading the numbers
- These are average-case values, chosen for comparability. The per-chip WCETs live in
Include/Test/Chip/and are the numbers to design against. TBDmeans the port exists and builds, but that measurement has not been taken on hardware yet.N/Ameans the operation does not apply to that platform (for example, a memory pool that the port does not enable).- No "cheating" optimizations are used: no toolchain-specific peephole sequences that break portability, no cooperative switches that avoid the scheduler, no average-case fast paths with unbounded worst cases.
- Timing values are cycles, not microseconds, so they are independent of the clock frequency. Multiply by the cycle time of the core to get wall-clock numbers.
