26

gcc takes the -mcpu= (or -march=) flags to produce optimized code for a particular CPU type. There's a plethora of arm variants, and the gcc Arm target also provides numerous FPU types.

Which -mcpu=/-march= flags and -mfpu= flags are the proper/native ones to use when compiling C code on a Raspberry Pi ?

4 Answers 4

11

This depends on what libraries you wish to link your code with. If you are using the Raspbian images, the architecture is "armhf" and the compilation flags are:

-march=armv6
-mfpu=vfp
-mfloat-abi=hard

If you are compiling for Debian "armel" arch, the compilation flags are different.

11

The RPI ARM core is an ARM 1176jzf-S, the suitable flags should then be

-march=armv6zk -mcpu=arm1176jzf-s -mfloat-abi=hard -mfpu=vfp

Drop the -mfloat-abi=hard -mfpu=vfp when on a soft float distro.

These flags can be found by running gcc -mcpu=native -march=native -Q --help=target on gcc >= 4.7`

2
  • Running gcc -mcpu=native -march=native -Q --help=target gives me *** Error in gcc': double free or corruption (top): 0x0020c5a8 ***`, on Raspbian Jessie 4.4.13-v7+, armv7l.
    – tsbertalan
    Nov 27, 2016 at 15:42
  • If I run that gcc command on a pi 3 I get -mfloat-abi=hard -mhard-float -msoft-float as part of the output. I believe all pis are hard-float, no?
    – vesperto
    Sep 15, 2021 at 14:54
8

I found that this set should be the optimal:

-march=armv6 -mfloat-abi=hard -mfpu=vfp

(the -mfloat-abi=hard, of course only when you use an armhf distro)

3

I can't answer about -mfpu flag, but I'd suggest to try these first:

-march=native
-mcpu=native
-mtune=native

As reported in GCC manual page related to ARM options:

-march=native causes the compiler to auto-detect the architecture of the build computer. At present, this feature is only supported on Linux, and not all architectures are recognized. If the auto-detect is unsuccessful the option has no effect.

-mcpu=native causes the compiler to auto-detect the CPU of the build computer. At present, this feature is only supported on Linux, and not all architectures are recognized. If the auto-detect is unsuccessful the option has no effect.

-mtune=native causes the compiler to auto-detect the CPU of the build computer. At present, this feature is only supported on Linux, and not all architectures are recognized. If the auto-detect is unsuccessful the option has no effect.

You can then add -Q -v to your GCC flags to see what optimizations are enabled and proceed to further optimizations if necessary.

This is the output using -march=native with a sample program on my Raspberry Pi:

#> gcc -march=native -Q -v test.c -o test
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/arm-linux-gnueabihf/4.6/lto-wrapper
Target: arm-linux-gnueabihf
Configured with: ../src/configure -v --with-pkgversion='Debian 4.6.3-8+rpi1' --with-bugurl=file:///usr/share/doc/gcc-4.6/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.6 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.6 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --enable-objc-gc --disable-sjlj-exceptions --with-arch=armv6 --with-fpu=vfp --with-float=hard --enable-checking=release --build=arm-linux-gnueabihf --host=arm-linux-gnueabihf --target=arm-linux-gnueabihf
Thread model: posix
gcc version 4.6.3 (Debian 4.6.3-8+rpi1) 
COLLECT_GCC_OPTIONS='-march=native' '-Q' '-v' '-o' 'test' '-mfloat-abi=hard' '-mfpu=vfp'
 /usr/lib/gcc/arm-linux-gnueabihf/4.6/cc1 -v -imultilib . -imultiarch arm-linux-gnueabihf test.c -dumpbase test.c -march=native -mfloat-abi=hard -mfpu=vfp -auxbase test -version -o /tmp/cc1rCJ4W.s
cc1: error: bad value (native) for -march switch
GNU C (Debian 4.6.3-8+rpi1) version 4.6.3 (arm-linux-gnueabihf)
    compiled by GNU C version 4.6.3, GMP version 5.0.5, MPFR version 3.1.0-p10, MPC version 0.9
GGC heuristics: --param ggc-min-expand=38 --param ggc-min-heapsize=15522
ignoring nonexistent directory "/usr/local/include/arm-linux-gnueabihf"
ignoring nonexistent directory "/usr/lib/gcc/arm-linux-gnueabihf/4.6/../../../../arm-linux-gnueabihf/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/lib/gcc/arm-linux-gnueabihf/4.6/include
 /usr/local/include
 /usr/lib/gcc/arm-linux-gnueabihf/4.6/include-fixed
 /usr/include/arm-linux-gnueabihf
 /usr/include
End of search list.
GNU C (Debian 4.6.3-8+rpi1) version 4.6.3 (arm-linux-gnueabihf)
    compiled by GNU C version 4.6.3, GMP version 5.0.5, MPFR version 3.1.0-p10, MPC version 0.9
GGC heuristics: --param ggc-min-expand=38 --param ggc-min-heapsize=15522
options passed:  -v -imultilib . -imultiarch arm-linux-gnueabihf test.c
 -march=native -mfloat-abi=hard -mfpu=vfp
options enabled:  -fauto-inc-dec -fbranch-count-reg -fcommon
 -fdelete-null-pointer-checks -fdwarf2-cfi-asm -fearly-inlining
 -feliminate-unused-debug-types -ffunction-cse -fgcse-lm -fident
 -finline-functions-called-once -fira-share-save-slots
 -fira-share-spill-slots -fivopts -fkeep-static-consts -fleading-underscore
 -fmath-errno -fmerge-debug-strings -fmove-loop-invariants -fpeephole
 -fprefetch-loop-arrays -freg-struct-return -fsched-critical-path-heuristic
 -fsched-dep-count-heuristic -fsched-group-heuristic -fsched-interblock
 -fsched-last-insn-heuristic -fsched-rank-heuristic -fsched-spec
 -fsched-spec-insn-heuristic -fsched-stalled-insns-dep -fshow-column
 -fsigned-zeros -fsplit-ivs-in-unroller -fstrict-volatile-bitfields
 -ftrapping-math -ftree-cselim -ftree-forwprop -ftree-loop-if-convert
 -ftree-loop-im -ftree-loop-ivcanon -ftree-loop-optimize
 -ftree-parallelize-loops= -ftree-phiprop -ftree-pta -ftree-reassoc
 -ftree-scev-cprop -ftree-slp-vectorize -ftree-vect-loop-version
 -funit-at-a-time -fvar-tracking -fvar-tracking-assignments
 -fzero-initialized-in-bss -mglibc -mlittle-endian -msched-prolog

Execution times (seconds)
 TOTAL                 :   0.00             0.00             0.00                  8 kB
8
  • 1
    -march=native isn't implemented for ARM processors in gcc. (at least not gcc shipping with Raspberrian)
    – nos
    Sep 29, 2012 at 12:14
  • @nos: as you can read in my answer, this page says that -march=native is implemented for ARM GCC. The Raspberry Pi may be an unsupported (and thus undetected) architecture, in that case -march=native has no effect.
    – Avio
    Sep 29, 2012 at 12:30
  • 2
    gcc on my Raspberrian says: $ gcc -march=native test.c cc1: error: bad value (native) for -march switch , it says the same in your output . (same with -mcpu as well)
    – nos
    Sep 29, 2012 at 13:41
  • 1
    Same version as me. Look in the output you posted, it's hidden in all the verboseness with the -v flag. After the line saying COLLECT_GCC_OPTIONS ...
    – nos
    Sep 29, 2012 at 13:47
  • 1
    @nos: ok, it seems not supported in this version. The strange thing is that I can't find the changelog where -march=native has been introduced also for ARM.
    – Avio
    Sep 29, 2012 at 13:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.