Last week I wrote about strange assembler messages on new PCs and I mentioned there could be performance issues when you don’t use -march=native
.
-march=native
is very good if you only plan to run your code on a specific computer, or you allow people to compile it themselves from source.
So what happens if you drop that flag? Well, if no flags are specified explicitly, GCC will usually automatically apply -mtune=generic -march=x86-64
.
This should be compatible with all x64 machines since Intel Core2 (2006) and AMD Opteron (2003).
(You can verify this by running echo "int main {return 0;}" | gcc -O2 -x c -v -Q -
).
This is fairly generic.
What is this generic compilation good for? Well, as a rule of thumb, you should always keep your compilations generic when you are publishing binaries that could run on many different processors. Any specific architecture you’ll compile for might break on an older or different (AMD vs. Intel for instance).
This rule has a drawback though – performance!
- Intel claims that there is a 17%-22% improvement when the
march
andmtune
flags are set properly, and not justgeneric
,x86-64
ornocona
is used. - According to Phoronix, there is some benefit to be had from using the correct
march
flags – but there might also be a regression. Luckily, those are expected to be fixed by GCC 4.9.0.
So what if you decide performance is important? Your stability will suffer:
- If you compile on a new architecture (say, Core i7-4000) – it might crash on older architecture (Core i7-3000) if specific unknown assembly command is reached. You might not even know if it will fail until you test all features in your code, and reach 100% code coverage.
- If set, the
mtune
flag will output an error if the target architecture doesn’t match compiled architecture and prevent program from running altogether. This is a safety option that you should consider using if compiling for specific architectures.
So if you decide to compile for specific architectures, you can find out what architecture GCC thinks you’re on by running
gcc -march=native -Q --help=target | grep march
Some Processor reference flags:
- Intel Core 2 Duo –
-march=core2
- Nehalem-based Xeons –
-march=corei7
- Sandy Bridge based Xeons (E3-12xx series, E5-14xx/24xx series, E5-16xx/26xx/46xx series) –
-march=corei7-avx
for GCC versions < 4.9 and-march=sandybridge
for GCC versions 4.9 and newer. - Ivy Bridge (Intel iN 3XXX and Xeons E3-12xx v2-series, E5-14xx v2/24xx v2-series, E5-16xx v2/26xx v2/46xx v2-series, E7-28xx v2/48xx v2/88xx v2-series) –
-march=core-avx-i
- Haswell (Intel iN 4XXX and Xeons E3-1xxx v3-series, E5-1xxx v3-series, E5-2xxx v3-series) –
-march=core-avx2
Leave a Reply