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() endLaunching 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> times12-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> infoDict{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…