gcc 的 -march=native 是一个方便的选项吗?有什么魔法是你无法手动获得的吗?

问题描述 投票:0回答:1

当使用 gcc 的

-march=native
选项时,它设置了许多标志/选项, 但是这是否可以通过手动设置所有内容来复制,或者是否有一些设置在手动设置时不会暴露给用户?

复制我的意思是你可以在没有

native
的情况下自己设置所有内容并生成相同的二进制文件,当然你可以使用
-march
指定微架构。

gcc compilation cross-compiling compiler-optimization compiler-options
1个回答
1
投票

根据

gcc -v -march=native foo.c
,传递给实际 C 到 asm 编译器 (
cc1
) 的选项不包括“native”,仅包含 arch/tune 和一些缓存大小参数。 所以,是的,您可以将相同的选项传递给交叉编译器,而不会错过任何东西。我不知道缓存大小选项有多大影响,也许对使用 NT 存储的循环阈值有多大影响(如果有的话)对某些目标执行此操作。

以及针对 GCC 所了解的每个 ISA 扩展的显式

-mabc
-mno-xyz
选项,因此它可以优化例如对于 CPUID 不公开某些功能的 VM,或者对于 Ice Lake 之前没有 AVX/FMA/BMI 扩展的 Pentium/Celeron,或者缺少 AVX-512 的 Ice Lake Pentium/Celeron,与
-march=icelake-client

不同

我已经在 GNU/Arch Linux 上手动换行了 x86-64 GCC 的终端输出:

$ gcc -v -march=native spawn.c
...
gcc version 13.2.1 20230801 (GCC) 
...
COLLECT_GCC_OPTIONS='-v' '-march=native' '-dumpdir' 'a-'
 /usr/lib/gcc/x86_64-pc-linux-gnu/13.2.1/cc1 -quiet -v spawn.c -march=skylake  \
-mmmx mpopcnt -msse -msse2 -msse3 -mssse3 -msse4.1 -msse4.2 -mavx -mavx2 -mno-sse4a \
-mno-fma4 -mno-xop -mfma -mno-avx512f -mbmi -mbmi2 -maes -mpclmul -mno-avx512vl \
-mno-avx512bw -mno-avx512dq -mno-avx512cd -mno-avx512er -mno-avx512pf -mno-avx512vbmi \
-mno-avx512ifma -mno-avx5124vnniw -mno-avx5124fmaps -mno-avx512vpopcntdq -mno-avx512vbmi2\
-mno-gfni -mno-vpclmulqdq -mno-avx512vnni -mno-avx512bitalg -mno-avx512bf16 \
-mno-avx512vp2intersect -mno-3dnow -madx -mabm -mno-cldemote -mclflushopt -mno-clwb \
-mno-clzero -mcx16 -mno-enqcmd  -mf16c -mfsgsbase -mfxsr -mno-hle -msahf -mno-lwp -mlzcnt\
-mmovbe -mno-movdir64b -mno-movdiri -mno-mwaitx -mno-pconfig -mno-pku -mno-prefetchwt1 \
-mprfchw -mno-ptwrite -mno-rdpid -mrdrnd -mrdseed -mno-rtm -mno-serialize -msgx -mno-sha \
-mno-shstk -mno-tbm -mno-tsxldtrk -mno-vaes -mno-waitpkg -mno-wbnoinvd -mxsave -mxsavec \
-mxsaveopt -mxsaves -mno-amx-tile -mno-amx-int8 -mno-amx-bf16 -mno-uintr -mno-hreset \
-mno-kl -mno-widekl -mno-avxvnni -mno-avx512fp16 -mno-avxifma -mno-avxvnniint8 \
-mno-avxneconvert -mno-cmpccxadd -mno-amx-fp16 -mno-prefetchi -mno-raoint \
-mno-amx-complex \
\
--param l1-cache-size=32 --param l1-cache-line-size=64 \
--param l2-cache-size=8192 -mtune=skylake \
-quiet -dumpdir a- -dumpbase spawn.c -dumpbase-ext .c -version -o /tmp/ccj4afQ8.s
...
 as -v --64 -o /tmp/ccb6usSK.o /tmp/ccj4afQ8.s
...

所以“本地”仍然存在于环境中,但我不希望

cc1
将其拉出来。
-m
-mmmx
之间的所有
-mno-amx-complex
选项都是我的 i7-6700k CPU 有/没有的 Intel 和 AMD ISA 扩展。所以传递给
-march=skylake
cc1
可能是多余的;它设置的所有内容都会被
-m
功能选项和
-mtune=skylake
覆盖。

在最后几行带有

--param
的选项中,8192 KiB 实际上是我的 i7-6700k (4c8t) 上 L3 末级缓存的大小。当设计 GCC 的这一部分时,最后一级共享缓存通常是 L2,但现在三级缓存很常见(每核私有缓存有两级,因此 L2 大小的缓存阻塞在某些情况下可能是合理的) )所以无论如何,大概没有人愿意将选项重命名为
llc-size
,并且如果
cc1
“驱动程序”前端刚刚通过最后一个,那么通过
cc1plus
/
gcc
调整启发式的方式就可以工作。级缓存大小。

Skylake 具有 32 KiB L1d 和 32 KiB L1i 缓存。所有级别的行大小均为 64 字节。 (L2 有一个“空间预取器”,喜欢完成一对对齐的行,因此存在 有点像 128 字节行 的弱行为)。

大概

-mtune=skylake
具有适合已知 I-cache / uop-cache 大小的展开和内联启发式方法,并且
--param l1-cache-size=32
基于 L1d。某些 CPU 的尺寸有所不同,例如 Ice Lake 和 Alder Lake P 核(48K L1d / 32K L1i)具有不同的尺寸,或者 Zen 1 有 32K L1d / 64K L1i。


LTO 类似,我认为

我只看到

--param l1-cache-size=32
和其他缓存选项被传递到
cc1
(C 到 GIMPLE + asm 编译器),而不是
lto1
(GIMPLE 到 asm 重新优化器)。我怀疑它们不是很重要,而且 IDK 如果现代 GCC 中的任何东西仍然依赖于它们,至少对于 x86 来说是这样。

更多选项通过

COLLECT_GCC_OPTIONS=
中的环境传递,其中末尾仍包含原始命令行参数。所以
-march=native
就在那里,在
-march=skylake -mabc -mno-xyz -mtune=skylake
选项之后。但是调用
lto1
不包含这一点,它在 -mtune=skylake
 之后停止,所以我认为 
-flto
 的实际 LTO 优化过程仍然完全由其命令行控制,而不是由它运行的机器控制。

© www.soinside.com 2019 - 2024. All rights reserved.