Zmei's blog

A place for random thoughts and observations. Mostly embedded, cars and DevOps

View on GitHub
5 September 2023

GCC compiler performance

by Ivan

What?

A totally unscientific benchmark of GCC on a real project that I’m currently working.

Why?

Because switching from GCC 6 to GCC12 felt slow and I wanted to know exactly how much slower it really is.

Background

It’s a real project, a custom firmware for a Cortex-M4F MCU (Atmel AT-SAME51 to be specific). It’s developed mainly in plain old C, with a bit of C++ thrown in. Even when C++ is used, it’s mostly as C-with-classes. The specific compiler options in place are:

-Os 
-mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 
-ffunction-sections -mlong-calls 
-Waddress -Wformat-nonliteral -Wformat-security -Wformat -Winit-self -Wmissing-declarations 
-Wno-multichar -Wunreachable-code -Wwrite-strings -Wpointer-arith -Wfloat-equal -Wparentheses 
-Wunused-parameter -Wunused-variable -Wreturn-type -Wuninitialized -Wextra -Wall  
-std=gnu11 -MD -MT

Methodology

Execute the below script two times, changing PATH to point to different compiler versions.

test_compile () {
    sleep 30
    make clean
    time make -j4 | grep real
}

for i in {1..10}; do test_compile; done

Basically compile the firmware 10 times in a loop, using up to 4 parallel compiler invokations - as this is the number of cores that I have on my setup.

Raw Results

GCC 6.3.1

$ arm-none-eabi-gcc --version 
arm-none-eabi-gcc (Atmel build: 508) 6.3.1 20170620 (release) [ARM/embedded-6-branch revision 249437]

$ ./test_compile.sh | grep real
real	0m13,659s
real	0m14,090s
real	0m15,397s
real	0m14,367s
real	0m14,815s
real	0m15,611s
real	0m18,213s
real	0m15,756s
real	0m18,644s
real	0m17,026s

GCC 12.2

$ arm-none-eabi-gcc --version 
arm-none-eabi-gcc (Arm GNU Toolchain 12.2.MPACBTI-Rel1 (Build arm-12-mpacbti.34)) 12.2.1 20230214

$ ./test_compile.sh | grep real
real	0m20,078s
real	0m22,832s
real	0m19,660s
real	0m19,067s
real	0m18,097s
real	0m18,159s
real	0m19,469s
real	0m19,113s
real	0m18,993s
real	0m20,311s

Results:

Build time

Build time in seconds:

GCC version Avg. time StdDev
6.3.1 15.757 1.616
12.2 19.578 1.281

Binary size

Sizes in bytes as obtained from arm-none-eabi-size:

GCC version Text Data Bss Total
6.3.1 54704 228 129344 184276
12.2 53752 220 129656 183628

Conclusion

GCC 12 is around 25% slower, which is noticeable even with this small project if doing a full build. I don’t have a statistic how much of that time is spent between the compiler and linker but subjectively even building and linking only a few files do seem slower. On the plus side, GCC 12 produces a binary that’s ~600 bytes smaller - which is rarely a deal-breaker but it may be under specific circumstances.

tags: