Profiling
This section summarizes some techniques to determine timing and memory allocation measures for Modia3D. The various approaches are demonstrated with models from directory Modia3D/test/Profiling.
@time
The simplest technique is to put @time in front of the statement that should be measured, such as:
# File Modia3D/test/Profiling/BouncingSphere_time.jl
module BouncingSphereSimulation_time
@time begin BouncingSphere = Model3D(
...
)
end
@time bouncingSphere = @instantiateModel(...)
@time simulate!(bouncingSphere,...)
@time plot(bouncingSphere, ...)
endThis gives the following output:
0.000116 seconds (199 allocations: 12.344 KiB)
Instantiating model Main.BouncingSphereSimulation.BouncingSphere
1.106054 seconds (2.40 M allocations: 150.386 MiB, 3.92% gc time, 62.47% compilation time)
0.322050 seconds (579.29 k allocations: 32.774 MiB, 5.81% compilation time)
0.077613 seconds (1.74 k allocations: 97.844 KiB)The second line
1.106054 seconds (2.40 M allocations: 150.386 MiB, 3.92% gc time, 62.47% compilation time)means the following:
- The total time spent in this statement was 1.106054 seconds
- 62.47% of this time was used to compile Julia code.
- 3.92% of this time was used by the garbage collector, so was used to find and remove allocated memory that is no longer in use.
- There have been 2.5 million allocations of memory. In total 150.386 Mega-Bytes have been allocated.
If a @time output contains gc time and/or compilation time it might be useful to just re-run the file, in order that the total time better reflects the execution time. In a second run compilation time should no longer be present.
Modia3D must allocate memory at the beginning of a simulate!(..) run for its internal data structure. After initialization, no memory should be allocated. However, with the @time macro it is not possible to figure out whether this is the case. Use instead option logTiming=true, see next section.
logTiming
Function simulate!(..., logTiming=true, ...) has keyword argument logTiming. When set to true, the result of the @timeit macro of the TimerOutputs package is shown. Function simulate!(..) and Modia3D are instrumented with this timer. Example:
# File Modia3D/test/Profiling/Mobile.jl
module MobileWithLogTiming
...
const enableVisualization = false
const tolerance = 1e-4
...
@time mobile = @instantiateModel(..., logExecution=true, ...)
...
@time simulate!(mobile, ...)
@time simulate!(mobile, log=true, logTiming=true, ...)
endThe @time macro should be used for @instantiateModel and simulate! in order to get information, whether allocation of storage is due to compilation and/or garbage collection. If the second simulate!(..) shows such allocation, the profiling run should be repeated.
@instantiateModel should have flag logExecution=true, in order that the generated function getDerivatives!(..) is called twice to force compilation of this function.
The logTiming=true flag generates the following output in this case:
Instantiating model Main.MobileWithLogTiming.Mobile
Execute getDerivatives
First executions of getDerivatives
1.363270 seconds (548.47 k allocations: 45.652 MiB, 2.47% gc time, 99.56% compilation time)
0.002773 seconds (18.82 k allocations: 1.157 MiB)
2.540190 seconds (7.17 M allocations: 264.371 MiB, 2.62% gc time, 53.43% compilation time)
... first simulation:
8.341341 seconds (37.34 M allocations: 2.236 GiB, 3.36% gc time)
... second simulation:
... Simulate model Mobile
Initialization at time = 0.0 s
Termination of Mobile at time = 5.0 s
cpuTime = 11.7 s
allocated = 2290.0 MiB
algorithm = CVODE_BDF
FloatType = Float64
interval = 0.01 s
tolerance = 0.0001 (relative tolerance)
nStates = 188
nResults = 501
nGetDerivatives = 1968 (total number of getDerivatives! calls)
nf = 1465 (number of getDerivatives! calls from integrator)
nZeroCrossings = 0 (number of getDerivatives! calls for zero crossing detection)
nJac = 6 (number of Jacobian computations)
nAcceptedSteps = 281
nRejectedSteps = 3
nErrTestFails = 3
nTimeEvents = 0
nStateEvents = 0
nRestartEvents = 0
... Timings for simulation of Mobile:
──────────────────────────────────────────────────────────────────────────────────────────────
Time Allocations
────────────────────── ───────────────────────
Tot / % measured: 11.8s / 99.0% 2.24GiB / 100%
Section ncalls time %tot avg alloc %tot avg
──────────────────────────────────────────────────────────────────────────────────────────────
simulate! 1 11.7s 100% 11.7s 2.24GiB 100% 2.24GiB
solve 1 11.7s 100% 11.7s 2.23GiB 100% 2.23GiB
getDerivatives! 1.97k 11.7s 100% 5.93ms 2.24GiB 100% 1.16MiB
LinearEquationsIteration 1.97k 11.6s 99.3% 5.91ms 2.22GiB 99.4% 1.16MiB
luA ldiv! 1.97k 4.65s 39.7% 2.36ms 1.68MiB 0.07% 896B
Modia3D 189k 3.56s 30.4% 18.8μs 905KiB 0.04% 4.90B
Modia3D_2 185k 2.57s 22.0% 13.9μs 5.16KiB 0.00% 0.03B
Modia3D_2 computeForcesAndResiduals 185k 638ms 5.45% 3.45μs 0.00B 0.00% 0.00B
Modia3D_2 computeKinematics! 185k 566ms 4.83% 3.06μs 0.00B 0.00% 0.00B
Modia3D_1 1.97k 50.3ms 0.43% 25.6μs 5.16KiB 0.00% 2.68B
Modia3D_1 computeKinematics! 1.97k 22.4ms 0.19% 11.4μs 0.00B 0.00% 0.00B
init! 1 9.46ms 0.08% 9.46ms 2.03MiB 0.09% 2.03MiB
Modia3D_1 computeForcesAndResiduals 1.97k 8.00ms 0.07% 4.07μs 0.00B 0.00% 0.00B
Modia3D_3 1.97k 584μs 0.00% 297ns 0.00B 0.00% 0.00B
ODEProblem 1 38.2μs 0.00% 38.2μs 2.58KiB 0.00% 2.58KiB
Modia3D_4 isTerminal 1 400ns 0.00% 400ns 0.00B 0.00% 0.00B
──────────────────────────────────────────────────────────────────────────────────────────────
11.999957 seconds (37.34 M allocations: 2.237 GiB, 2.67% gc time)The meaning of the first lines
First executions of getDerivatives
1.363270 seconds (548.47 k allocations: 45.652 MiB, 2.47% gc time, 99.56% compilation time)
0.002773 seconds (18.82 k allocations: 1.157 MiB)
2.540190 seconds (7.17 M allocations: 264.371 MiB, 2.62% gc time, 53.43% compilation time)is the following:
1.363270 secondsis the time for the first evaluation ofgetDerivatives!. This time is nearly completely used for compilation of this function0.002773 secondsis the time for the second evaluation ofgetDerivatives!. This time is nearly irrelevant for the timing of@instantiateModel.2.540190seconds is the total time spent in@instantiateModel, including the two calls ofgetDerivatives!. This time, together with (1.) shows the following:0.47*2.5 = 1.1seconds are used to process the model, generategetDerivatives!and processgetDerivatives!twice.0.53*2.5 = 1.32seconds are used to compilegetDerivatives!.
The meaning of column Section is the following:
@timeit instrumentation of simulate!(..)
| Column Section | Description |
|---|---|
simulate! | Time of simulate!(..), but without log outputs. |
init! | Time of init!(..), so model initialization. |
ODEProblem | Time of DifferentialEquations.ODEProblem(..), so setup of problem. |
solve | Time of DifferentialEquations.solve(..), so after init!(..). |
getDerivatives! | Time of getDerivatives!(..). |
LinearEquationsIteration | Time to build and solve linear equation systems inside getDerivatives!(..) |
luA ldiv! | Time to solve A*x=b with luA and ldiv! inside LinearEquationsIteration |
@timeit instrumentation of Modia3D
| Column Section | Description |
|---|---|
Modia3D | Total time spent in Modia3D functions. |
Modia3D_0 initializeVisualization | Time to initialize visualization (during init!(..)). |
Modia3D_1 | Time of leq_mode == 0 (= compute h(q,qd,gravity)). |
Modia3D_1 computeKinematics! | Time to compute position, velocity, acceleration with qdd=0. |
Modia3D_1 selectContactPairsWithEvent! | Time to call selectContactPairsWithEvent! (collision handling). |
Modia3D_1 selectContactPairsNoEvent! | Time to call selectContactPairsNoEvent! (collision handling). |
Modia3D_1 getDistances! | Time to call getDistances! (collision handling). |
Modia3D_1 dealWithContacts! | Time to call dealWithContacts! (collision handling). |
Modia3D_1 computeForcesAndResiduals | Time to compute forces/torques/residuals (without collision). |
Modia3D_2 | Time of leq_mode > 0 (= compute M(q)*qdd, for unit vectors of qdd). |
Modia3D_2 computeKinematics! | Time to compute accelerations with qdd = unit vector. |
Modia3D_2 computeForcesAndResiduals | Time to compute forces/torques/residuals for M(q)*qdd. |
Modia3D_3 | Time of leq_mode == -1. |
Modia3D_3 visualize! | Time of for obj in updateVisuElements ... visualize(..). |
Modia3D_3 exportAnimation | Time of for obj in allVisuElements ... push!(objectData, dat) |
Modia3D_4 isTerminal | Time of exportAnimation and closeVisualization during termination. |
How to instrument with @timeit
Further functions in Modia3D can be instrumented in the following way:
The timer of TimerOutputs is available as instantiatedModel.timer. Therefore, instrumenting a function call is done with:
TimerOutputs.@timeit instantiatedModel.timer "Modia3D XXX" functionCall(...)or
TimerOutputs.@timeit instantiatedModel.timer "Modia3D XXX" begin
statements
end