Archspec
Archspec is a Julia package to get access to the information provided by archspec-json
, part of the Archspec project.
CPU Microarchitectures
A CPU microarchitecture is modeled in Archspec.jl
by the Microarchitecture
structure. Instances of this structure are constructed automatically from archspec-json
to populate a dictionary of known microarchitectures:
julia> using Archspec
julia> Archspec.CPUTargets
Dict{String, Archspec.Microarchitecture} with 52 entries: "icelake" => Microarchitecture("icelake", Set(["sse4_1", "bmi1", "adx", "… "cannonlake" => Microarchitecture("cannonlake", Set(["adx", "clflushopt", "s… "x86_64_v2" => Microarchitecture("x86_64_v2", Set(["mmx", "sse2", "ssse3", … "sparc64" => Microarchitecture("sparc64", Set{String}(), Dict{String, Arc… "core2" => Microarchitecture("core2", Set(["mmx", "sse2", "ssse3", "sse… "broadwell" => Microarchitecture("broadwell", Set(["movbe", "mmx", "sse2", … "prescott" => Microarchitecture("prescott", Set(["mmx", "sse2", "sse3", "s… "graviton" => Microarchitecture("graviton", Set(["fp", "evtstrm", "sha2", … "thunderx2" => Microarchitecture("thunderx2", Set(["atomics", "evtstrm", "s… "power9le" => Microarchitecture("power9le", Set{String}(), Dict{String, Ar… "piledriver" => Microarchitecture("piledriver", Set(["abm", "mmx", "sse2", "… "x86_64_v3" => Microarchitecture("x86_64_v3", Set(["movbe", "abm", "mmx", "… "steamroller" => Microarchitecture("steamroller", Set(["abm", "mmx", "sse2", … "riscv64" => Microarchitecture("riscv64", Set{String}(), Dict{String, Arc… "graviton2" => Microarchitecture("graviton2", Set(["atomics", "fp", "lrcpc"… "westmere" => Microarchitecture("westmere", Set(["mmx", "sse2", "ssse3", "… "zen2" => Microarchitecture("zen2", Set(["xsaveopt", "abm", "sse2", "b… "power8le" => Microarchitecture("power8le", Set{String}(), Dict{String, Ar… "nehalem" => Microarchitecture("nehalem", Set(["mmx", "sse2", "ssse3", "s… ⋮ => ⋮
Archspec.CPUTargets
maps the names of the microarchitectures to a corresponding Microarchitecture
object:
julia> using Archspec
julia> Archspec.CPUTargets["broadwell"]
Archspec.Microarchitecture("broadwell", Set(["movbe", "mmx", "sse2", "ssse3", "pclmulqdq", "rdrand", "bmi2", "rdseed", "aes", "avx", "sse4_2", "popcnt", "fma", "avx2", "sse", "sse4_1", "f16c", "bmi1", "adx"]), Dict{String, Archspec.Compiler}("apple-clang" => Archspec.Compiler("broadwell", "apple-clang", Archspec.CompilerSpec[Archspec.CompilerSpec("broadwell", "-march=broadwell -mtune=broadwell", VersionSpec("8.0.0-*"), "")]), "aocc" => Archspec.Compiler("broadwell", "aocc", Archspec.CompilerSpec[Archspec.CompilerSpec("broadwell", "-march=broadwell -mtune=broadwell", VersionSpec("2.2.0-*"), "")]), "intel" => Archspec.Compiler("broadwell", "intel", Archspec.CompilerSpec[Archspec.CompilerSpec("broadwell", "-march=broadwell -mtune=broadwell", VersionSpec("18.0.0-*"), "")]), "gcc" => Archspec.Compiler("broadwell", "gcc", Archspec.CompilerSpec[Archspec.CompilerSpec("broadwell", "-march=broadwell -mtune=broadwell", VersionSpec("4.9.0-*"), "")]), "clang" => Archspec.Compiler("broadwell", "clang", Archspec.CompilerSpec[Archspec.CompilerSpec("broadwell", "-march=broadwell -mtune=broadwell", VersionSpec("3.9.0-*"), "")])), ["haswell"], "GenuineIntel")
Basic queries
A Microarchitecture
object can be queried for its name and vendor:
julia> uarch = Archspec.CPUTargets["broadwell"];
julia> uarch.name
"broadwell"
julia> uarch.vendor
"GenuineIntel"
A microarchitecture can also be queried for features:
julia> "avx" ∈ Archspec.CPUTargets["broadwell"]
true
julia> "avx" ∈ Archspec.CPUTargets["thunderx2"]
false
julia> "neon" ∈ Archspec.CPUTargets["thunderx2"]
true
The verbatim list of features for each object is stored in the features
field:
julia> Archspec.CPUTargets["nehalem"].features
Set{String} with 7 elements:
"mmx"
"sse2"
"ssse3"
"sse4_2"
"popcnt"
"sse"
"sse4_1"
julia> Archspec.CPUTargets["thunderx2"].features
Set{String} with 11 elements:
"atomics"
"evtstrm"
"sha2"
"asimdrdm"
"aes"
"cpuid"
"asimd"
"crc32"
"sha1"
"pmull"
"fp"
julia> Archspec.CPUTargets["power9le"].features
Set{String}()
Finally, you can also make set comparison operations between microarchitectures:
julia> Archspec.CPUTargets["nehalem"] < Archspec.CPUTargets["broadwell"]
true
julia> Archspec.CPUTargets["nehalem"] == Archspec.CPUTargets["broadwell"]
false
julia> Archspec.CPUTargets["nehalem"] >= Archspec.CPUTargets["broadwell"]
false
julia> Archspec.CPUTargets["nehalem"] > Archspec.CPUTargets["a64fx"]
false
Compiler's optimization flags
Another information that each microarchitecture object has available is which compiler flags needs to be used to emit code optimized for itself:
julia> optimization_flags(Archspec.CPUTargets["broadwell"], "clang", v"11.0.1")
"-march=broadwell -mtune=broadwell"
Sometimes compiler flags change across versions of the same compiler:
julia> optimization_flags(Archspec.CPUTargets["thunderx2"], "gcc", v"5.1")
"-march=armv8-a+crc+crypto"
julia> optimization_flags(Archspec.CPUTargets["thunderx2"], "gcc", v"9.1")
"-mcpu=thunderx2t99"
If a compiler is known to not be able to optimize for a given architecture an exception is raised:
julia> optimization_flags(Archspec.CPUTargets["icelake"], "gcc", v"4.8.5")
ERROR: cannot produce optimized binary for micro-architecture "icelake" with gcc@4.8.5
Stacktrace:
[1] error(s::String)
@ Base ./error.jl:33
[...]
API Reference
Archspec.Compiler
— TypeCompiler
Compiler
is a composite structure modeling a compiler for a given microarchitecture.
Archspec.CompilerSpec
— TypeCompilerSpec
CompilerSpec
is a composite structure modeling an instance of a compiler for a given microarchitecture and a specific version number, or range of versions.
Archspec.Microarchitecture
— TypeMicroarchitecture
Microarchitecture
is a composite structure modeling a CPU microarchitecture.
Archspec.optimization_flags
— Methodoptimization_flags(microarchitecture::Microarchitecture, compiler::String, version::VersionNumber)
Return the list of compiler flags for the given micro-architecture using the given compiler version.
julia> optimization_flags(Archspec.CPUTargets["x86_64_v2"], "gcc", v"5.2")
"-march=x86_64_v2 -mtune=generic -mcx16 -msahf -mpopcnt -msse3 -msse4.1 -msse4.2 -mssse3"
julia> optimization_flags(Archspec.CPUTargets["x86_64_v2"], "gcc", v"11.1")
"-march=x86_64_v2 -mtune=generic"
Base.in
— Methodin(feature::String, m::Microarchitecture) -> Bool
∈(feature::String, m::Microarchitecture) -> Bool
Return whether the given feature
is available in the microarchitecture m
.
julia> "sse3" in Archspec.CPUTargets["broadwell"]
true
julia> "avx512" in Archspec.CPUTargets["haswell"]
false