Tutorial on @snoop_llvm
Julia uses the LLVM compiler to generate machine code. Typically, the two main contributors to the overall compile time are inference and LLVM, and thus together @snoop_inference
and @snoop_llvm
collect fairly comprehensive data on the compiler.
@snoop_llvm
has a somewhat different design than @snoop_inference
: while @snoop_inference
runs in the same session that you'll be using for analysis (and thus requires that you remember to do the data gathering in a fresh session), @snoop_llvm
spawns a fresh process to collect the data. The downside is that you get less interactivity, as the data have to be written out in intermediate forms as a text file.
Add SnoopCompileCore and SnoopCompile to your environment
Here, we'll add these packages to your default environment.
using Pkg
Pkg.add(["SnoopCompileCore", "SnoopCompile"]);
Collecting the data
Here's a simple demonstration of usage:
julia> using SnoopCompileCore
julia> @snoop_llvm "func_names.csv" "llvm_timings.yaml" begin using InteractiveUtils @eval InteractiveUtils.peakflops() end
Launching new julia process to run commands... done.
julia> using SnoopCompile
julia> times, info = SnoopCompile.read_snoop_llvm("func_names.csv", "llvm_timings.yaml", tmin_secs = 0.005);
┌ Warning: Couldn't find julia_run_package_callbacks_492u503 └ @ SnoopCompile ~/work/SnoopCompile.jl/SnoopCompile.jl/src/parcel_snoop_llvm.jl:51 ┌ Warning: Couldn't find julia_#_include_from_serialized#862_672u677 └ @ SnoopCompile ~/work/SnoopCompile.jl/SnoopCompile.jl/src/parcel_snoop_llvm.jl:51 ┌ Warning: Couldn't find julia_#_include_from_serialized#862_672u690 └ @ SnoopCompile ~/work/SnoopCompile.jl/SnoopCompile.jl/src/parcel_snoop_llvm.jl:51 ┌ Warning: Couldn't find julia___require_prelocked_564u639 └ @ SnoopCompile ~/work/SnoopCompile.jl/SnoopCompile.jl/src/parcel_snoop_llvm.jl:51 ┌ Warning: Couldn't find julia___require_prelocked_564u589 └ @ SnoopCompile ~/work/SnoopCompile.jl/SnoopCompile.jl/src/parcel_snoop_llvm.jl:51 ┌ Warning: Couldn't find julia___require_prelocked_564u617 └ @ SnoopCompile ~/work/SnoopCompile.jl/SnoopCompile.jl/src/parcel_snoop_llvm.jl:51 ┌ Warning: Couldn't find julia___require_prelocked_564u633 └ @ SnoopCompile ~/work/SnoopCompile.jl/SnoopCompile.jl/src/parcel_snoop_llvm.jl:51 ┌ Warning: Couldn't find julia_#_require_search_from_serialized#878_1026u1064 └ @ SnoopCompile ~/work/SnoopCompile.jl/SnoopCompile.jl/src/parcel_snoop_llvm.jl:51 ┌ Warning: Couldn't find julia_#_require_search_from_serialized#878_1026u1042 └ @ SnoopCompile ~/work/SnoopCompile.jl/SnoopCompile.jl/src/parcel_snoop_llvm.jl:51 ┌ Warning: Couldn't find julia_#_require_search_from_serialized#878_1026u1081 └ @ SnoopCompile ~/work/SnoopCompile.jl/SnoopCompile.jl/src/parcel_snoop_llvm.jl:51 ┌ Warning: Couldn't find julia_#_require_search_from_serialized#878_1026u1073 └ @ SnoopCompile ~/work/SnoopCompile.jl/SnoopCompile.jl/src/parcel_snoop_llvm.jl:51 ┌ Warning: Couldn't find julia_#_require_search_from_serialized#878_863u918 └ @ SnoopCompile ~/work/SnoopCompile.jl/SnoopCompile.jl/src/parcel_snoop_llvm.jl:51 ┌ Warning: Couldn't find julia_#_require_search_from_serialized#878_863u910 └ @ SnoopCompile ~/work/SnoopCompile.jl/SnoopCompile.jl/src/parcel_snoop_llvm.jl:51 ┌ Warning: Couldn't find julia_#_require_search_from_serialized#878_863u879 └ @ SnoopCompile ~/work/SnoopCompile.jl/SnoopCompile.jl/src/parcel_snoop_llvm.jl:51 ┌ Warning: Couldn't find julia_#_require_search_from_serialized#878_863u901 └ @ SnoopCompile ~/work/SnoopCompile.jl/SnoopCompile.jl/src/parcel_snoop_llvm.jl:51 ┌ Warning: Couldn't find julia_#_include_from_serialized#862_927u945 └ @ SnoopCompile ~/work/SnoopCompile.jl/SnoopCompile.jl/src/parcel_snoop_llvm.jl:51 ┌ Warning: Couldn't find julia_#_include_from_serialized#862_927u932 └ @ SnoopCompile ~/work/SnoopCompile.jl/SnoopCompile.jl/src/parcel_snoop_llvm.jl:51
This will write two files, "func_names.csv"
and "llvm_timings.yaml"
, in your current working directory. Let's look at what was read from these files:
julia> times
12-element Vector{Pair{Float64, Vector{String}}}: 0.005272079 => ["Tuple{typeof(Base.require_stdlib), Base.PkgId, Nothing, Module}"] 0.005479317 => ["Tuple{typeof(Base._tryrequire_from_serialized), Base.PkgId, UInt128}"] 0.006859704 => ["Tuple{typeof(Base.run_package_callbacks), Base.PkgId}", "julia_run_package_callbacks_492u503"] 0.007598288 => ["Tuple{typeof(Base._tryrequire_from_serialized), Base.PkgId, String, Nothing}"] 0.009295057 => ["Tuple{typeof(Base._tryrequire_from_serialized), Base.PkgId, String, String}"] 0.013945092 => ["Tuple{typeof(Base.register_restored_modules), Core.SimpleVector, Base.PkgId, String}"] 0.017224596 => ["Tuple{typeof(Base.run_extension_callbacks), Base.PkgId}"] 0.024840508 => ["julia_#_include_from_serialized#862_927u945", "julia_#_include_from_serialized#862_927u932", "Tuple{Base.var\"##_include_from_serialized#862\", Bool, typeof(Base._include_from_serialized), Base.PkgId, String, Nothing, Array{Any, 1}}"] 0.025225649 => ["Tuple{Base.var\"##_include_from_serialized#862\", Bool, typeof(Base._include_from_serialized), Base.PkgId, String, String, Array{Any, 1}}", "julia_#_include_from_serialized#862_672u677", "julia_#_include_from_serialized#862_672u690"] 0.037003489 => ["julia___require_prelocked_564u639", "julia___require_prelocked_564u589", "julia___require_prelocked_564u617", "Tuple{typeof(Base.__require_prelocked), Base.PkgId, Nothing}", "julia___require_prelocked_564u633"] 0.091129405 => ["julia_#_require_search_from_serialized#878_863u918", "julia_#_require_search_from_serialized#878_863u910", "julia_#_require_search_from_serialized#878_863u879", "Tuple{Base.var\"##_require_search_from_serialized#878\", Nothing, Array{String, 1}, typeof(Base._require_search_from_serialized), Base.PkgId, String, UInt128, Bool}", "julia_#_require_search_from_serialized#878_863u901"] 0.094882888 => ["Tuple{Base.var\"##_require_search_from_serialized#878\", Base.Dict{String, Int64}, Array{String, 1}, typeof(Base._require_search_from_serialized), Base.PkgId, String, UInt128, Bool}", "julia_#_require_search_from_serialized#878_1026u1064", "julia_#_require_search_from_serialized#878_1026u1042", "julia_#_require_search_from_serialized#878_1026u1081", "julia_#_require_search_from_serialized#878_1026u1073"]
julia> info
Dict{String, @NamedTuple{before::@NamedTuple{instructions::Int64, basicblocks::Int64}, after::@NamedTuple{instructions::Int64, basicblocks::Int64}}} with 12 entries: "Tuple{typeof(Base._tryr… => (before = (instructions = 641, basicblocks = 108… "Tuple{typeof(Base.__req… => (before = (instructions = 3, basicblocks = 1), a… "Tuple{Base.var\"##_incl… => (before = (instructions = 1921, basicblocks = 37… "Tuple{Base.var\"##_requ… => (before = (instructions = 3, basicblocks = 1), a… "Tuple{typeof(Base.run_e… => (before = (instructions = 965, basicblocks = 167… "Tuple{typeof(Base.regis… => (before = (instructions = 956, basicblocks = 154… "Tuple{typeof(Base._tryr… => (before = (instructions = 530, basicblocks = 98)… "Tuple{typeof(Base._tryr… => (before = (instructions = 435, basicblocks = 73)… "Tuple{typeof(Base.requi… => (before = (instructions = 437, basicblocks = 82)… "Tuple{Base.var\"##_requ… => (before = (instructions = 3, basicblocks = 1), a… "Tuple{typeof(Base.run_p… => (before = (instructions = 3, basicblocks = 1), a… "Tuple{Base.var\"##_incl… => (before = (instructions = 3, basicblocks = 1), a…