切腹のイラスト

GentooのCPU flagsを見直す(x86)

{
  date: "",
  category: "/unix-like",
  tags: ["Gentoo", "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の対応を確認する。

表: CPU featuresとCPU_FEATURES_X86の対応
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_X86cpuid2cpuflagsの差分は以下の通りとなった。

# 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のサンプルについては,いろんなマシンのものを確認して随時改善する予定。