project_options icon indicating copy to clipboard operation
project_options copied to clipboard

Test '-march=native' support for all architectures and platforms

Open ljishen opened this issue 2 years ago • 8 comments

This flag fails on some ARM platforms including the Apple M1 (1, 2). We may be able to check whether it is supported by using clang -march=native -cx /dev/null (1, 2) before adding to the compile options.

Upvote & Fund

  • I am using Polar.sh so you can upvote and help fund this issue. The funding is received once the issue is completed & confirmed by you.

  • Thank you in advance for helping prioritize & fund our backlog.

Fund with Polar

ljishen avatar Mar 06 '22 01:03 ljishen

Is this supported on other compilers like GCC and MSVC?

aminya avatar Mar 06 '22 02:03 aminya

I don't see the same problem with GCC. And I don't have an environment to test with MSVC.

ljishen avatar Mar 06 '22 06:03 ljishen

I tested inside Godbolt, and it seems that GCC doesn't support it either!

gcc arm https://godbolt.org/z/G93d8qPed

clang arm https://godbolt.org/z/zfTcTbhG9

It also seems that /arch:native doesn't actually work on MSVC. https://godbolt.org/z/G3W1EqeMo

It seems it only accepts the exact instruction set like AVX https://docs.microsoft.com/en-us/cpp/build/reference/arch-x64

aminya avatar Mar 06 '22 06:03 aminya

I found another issue while testing this.

ljishen avatar Mar 06 '22 06:03 ljishen

I tested inside Godbolt, and it seems that GCC doesn't support it either!

gcc arm https://godbolt.org/z/G93d8qPed

clang arm https://godbolt.org/z/zfTcTbhG9

It also seems that /arch:native doesn't actually work on MSVC. https://godbolt.org/z/G3W1EqeMo

It seems it only accepts the exact instruction set like AVX https://docs.microsoft.com/en-us/cpp/build/reference/arch-x64

I'm glad you found that. Maybe my ARM machine is supported by GCC but not clang. The key is that not all ARM machines are supported by these two compilers with that flag.

ljishen avatar Mar 06 '22 06:03 ljishen

I suspect that the reason why your GCC test on Godbolt doesn't work is that Godbolt uses cross-compiling on an x86_64 machine and the "native" flag means using the processor's features of the host machine for compiling code, which doesn't work if the toolchain is for Arm and you ask it to optimize for a different type of CPU (e.g., x86_64). Therefore, for cross-compiling, the flag should be explicit for a relevant type of CPU.

This article suggests that the optimization flag for x86 and Arm cannot be the same and we should use -mcpu for Arm and -march for x86: https://community.arm.com/arm-community-blogs/b/tools-software-ides-blog/posts/compiler-flags-across-architectures-march-mtune-and-mcpu

ljishen avatar Mar 07 '22 00:03 ljishen

If there is a deterministic and cross-platform way to do this, I will be open to doing that.

For GCC and clang, we can use [gcc/clang] -Werror [the test flag] -E -xc /dev/null and check the return code. For example, [gcc/clang] -Werror -march=native -E -xc /dev/null or [gcc/clang] -Werror -mcpu=native -E -xc /dev/null.

I guess MSVC will have a similar way to test, but I don't have the environment for testing.

Originally posted by @ljishen in https://github.com/cpp-best-practices/project_options/issues/98#issuecomment-1060233047

aminya avatar Mar 16 '22 22:03 aminya

I found a project that does this! We can use that https://github.com/scivision/cmake-cpu-detect

aminya avatar May 17 '22 07:05 aminya