切腹倶楽部
日々是切腹
GentooのCPU flagsを見直す(x86)
昨今のreproducible意識の高まりに伴い,ラップトップのGentooで使うパッケージを別マシンでコンパイルする為,効率的かつジェネリックなプロファイルを構築する需要が発生した。
CFLAGSの-march=は良いとして,特にPortageのCPU_FLAGS_X86について,今まではホスト兼ターゲットマシンのapp-portage/cpuid2cpuflagsの出力を脳死で使っていたものを,この機会にちゃんと確認しようと思った。
(あんま関係ないけどCFLAGSの値の検討にはapp-misc/resolve-march-nativeが便利。)
これはそのときの作業記録である。
前提知識
1. CPU features
CPUIDで取得できるやつ。 x86はいっぱい種類がある。 今回はこれを主に調査した。
cf. Linuxのarch/x86/include/asm/cpufeatures.h
https://github.com/torvalds/linux/blob/master/arch/x86/include/asm/cpufeatures.h
2. x86-64 psABI
Processor Specific Application Binary Interfaceの略.
IntelやAMDの提供するCPUには,拡張命令セットと呼ばれる「x86-64の仕様策定時点では定義されていなかったが,追加された命令」が多くに存在する.この状況に対し,2020年,AMD,Intel,Red Hat,SUSEは共同で,x86-64ベースラインの上に3つのx86-64マイクロアーキテクチャのレベルを定義.これが,x86-64 psABI*である.
「psABI @techistory」 2026/01/22閲覧
拡張命令を体系化したやつってことかな?
たまに見かけるx86-64-v3とかはこいつが元ネタらしい。
psABIの文書はGitLabで公開されているようだ: https://gitlab.com/x86-psABIs/x86-64-ABI
方針
psABIの適当なMicro-Architecture Levelを基本に,その他一般的な拡張命令を加えたCPU_FLAGS_X86を検討する。
普段使うマシンにはx86-64-v3とx86-64-v4のものがあるので,これら2つのLevelを対象にやっていく。
検討
まず,以下の資料を参考に,psABIで言及されているCPU featuresとGentooのCPU_FLAGS_X86の対応を確認する。
- abi.pdf
- gentoo/profiles/desc/cpu_flags_x86.desc at master · gentoo/gentoo
- x86 Options (Using the GNU Compiler Collection (GCC))
- Clang command line argument reference — Clang 23.0.0git documentation
| Micro-Architecture Level | CPU feature | GCC / Clang option | CPU_FLAGS_X86 |
|---|---|---|---|
| (baseline) | CMOV | n/a | n/a |
| CX8 | n/a | n/a | |
| FPU | -m80387 |
n/a | |
| FXSR | -mfxsr |
n/a | |
| MMX | -mmmx |
cpu_flags_x86_mmx |
|
| OSFXSR | -mfxsr |
n/a | |
| SCE | n/a | n/a | |
| SSE | -msse |
cpu_flags_x86_sse |
|
| SSE2 | -msse2 |
cpu_flags_x86_sse2 |
|
| x86-64-v2 | CMPXCHG16B | -mcx16 |
n/a |
| LAHF-SAHF | -msahf |
n/a | |
| POPCNT | -mpopcnt |
cpu_flags_x86_popcnt |
|
| SSE3 | -msse3 |
cpu_flags_x86_sse3 |
|
| SSE4_1 | -msse4.1 |
cpu_flags_x86_sse4_1 |
|
| SSE4_2 | -msse4.2 |
cpu_flags_x86_sse4_2 |
|
| SSSE3 | -mssse3 |
cpu_flags_x86_ssse3 |
|
| x86-64-v3 | AVX | -mavx |
cpu_flags_x86_avx |
| AVX2 | -mavx2 |
cpu_flags_x86_avx2 |
|
| BMI1 | -mbmi |
cpu_flags_x86_bmi1 |
|
| BMI2 | -mbmi2 |
cpu_flags_x86_bmi2 |
|
| F16C | -mf16c |
cpu_flags_x86_f16c |
|
| FMA | -mfma |
cpu_flags_x86_fma3 |
|
| LZCNT | -mlzcnt |
n/a | |
| MOVBE | -mmovbe |
n/a | |
| OSXSAVE | -mxsave |
n/a | |
| x86-64-v4 | AVX512F | -mavx512f |
cpu_flags_x86_avx512f |
| AVX512BW | -mavx512bw |
cpu_flags_x86_avx512bw |
|
| AVX512CD | -mavx512cd |
cpu_flags_x86_avx512cd |
|
| AVX512DQ | -mavx512dq |
cpu_flags_x86_avx512dq |
|
| AVX512VL | -mavx512vl |
cpu_flags_x86_avx512vl |
表から,対象のMicro-Architecture Levelをそのまま反映したCPU_FLAGS_X86は以下の通りである。
# x86-64-v3
CPU_FLAGS_X86_V3="avx avx2 bmi1 bmi2 f16c fma3 mmx popcnt sse sse2 sse3 sse4_1 sse4_2 ssse3"
# x86-64-v4
CPU_FLAGS_X86_V4="${CPU_FLAGS_X86_V3} avx512bw avx512cd avx512dq avx512f avx512vl"
ここで,筆者がアクセスできる各種マシンについて,CPUのMicro-Architecture Levelから導出したCPU_FLAGS_X86とcpuid2cpuflagsの差分は以下の通りとなった。
# Core i5-4460
CPU_FLAGS_X86="${CPU_FLAGS_X86_V3} aes mmxext pclmul rdrand"
# Core i5-8500
CPU_FLAGS_X86="${CPU_FLAGS_X86_V3} aes mmxext pclmul rdrand"
# Ryzen 3 3100
CPU_FLAGS_X86="${CPU_FLAGS_X86_V3} aes mmxext pclmul rdrand sha sse4a"
# Ryzen 5 5600G
CPU_FLAGS_X86="${CPU_FLAGS_X86_V3} aes mmxext pclmul rdrand sha sse4a vpclmulqdq"
# Ryzen AI 7 PRO 350
CPU_FLAGS_X86="${CPU_FLAGS_X86_V4} aes avx_vnni mmxext pclmul rdrand sha sse4a vpclmulqdq avx512_bf16 avx512_bitalg avx512_vbmi2 avx512_vnni avx512_vp2intersect avx512_vpopcntdq avx512ifma avx512vbmi"
# Xeon w5-2555X
CPU_FLAGS_X86="${CPU_FLAGS_X86_V4} aes amx_bf16 amx_int8 amx_tile avx_vnni mmxext pclmul rdrand sha vpclmulqdq avx512_bf16 avx512_bitalg avx512_fp16 avx512_vbmi2 avx512_vnni avx512_vpopcntdq avx512ifma avx512vbmi"
各Levelの最大公約数として,x86-64-v3にaes mmxext pclmul rdrandを,x86-64-v4にavx_vnni sha vpclmulqdq avx512_bf16 avx512_bitalg avx512_vbmi2 avx512_vnni avx512_vpopcntdq avx512ifma avx512vbmiを加えると以下のようになった。
# Core i5-4460
CPU_FLAGS_X86="${CPU_FLAGS_X86_V3}"
# Core i5-8500
CPU_FLAGS_X86="${CPU_FLAGS_X86_V3}"
# Ryzen 3 3100
CPU_FLAGS_X86="${CPU_FLAGS_X86_V3} sha sse4a"
# Ryzen 5 5600G
CPU_FLAGS_X86="${CPU_FLAGS_X86_V3} sha sse4a vpclmulqdq"
# Ryzen AI 7 PRO 350
CPU_FLAGS_X86="${CPU_FLAGS_X86_V4} avx512_vp2intersect sse4a"
# Xeon w5-2555X
CPU_FLAGS_X86="${CPU_FLAGS_X86_V4} amx_bf16 amx_int8 amx_tile avx512_fp16"
ええ感じではなかろうか。
結論
こうなった。
# x86-64-v3+
CPU_FLAGS_X86="avx avx2 bmi1 bmi2 f16c fma3 mmx popcnt sse sse2 sse3 sse4_1 sse4_2 ssse3"
CPU_FLAGS_X86="${CPU_FLAGS_X86} aes mmxext pclmul rdrand"
# x86-64-v4+
CPU_FLAGS_X86="${CPU_FLAGS_X86} avx512bw avx512cd avx512dq avx512f avx512vl"
CPU_FLAGS_X86="${CPU_FLAGS_X86} avx_vnni sha vpclmulqdq avx512_bf16 avx512_bitalg avx512_vbmi2 avx512_vnni avx512_vpopcntdq avx512ifma avx512vbmi"
CPU flagsのサンプルについては,いろんなマシンのものを確認して随時改善する予定。