Skip to content

Commit d371291

Browse files
add excessive scheduling time to time macro etc.
1 parent 77c5875 commit d371291

File tree

3 files changed

+46
-14
lines changed

3 files changed

+46
-14
lines changed

base/Base.jl

+3
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,9 @@ include("weakkeydict.jl")
424424
# ScopedValues
425425
include("scopedvalues.jl")
426426

427+
# used by task.jl
428+
const Workqueue_sched_times = ScopedValues.ScopedValue{Vector{UInt}}()
429+
427430
# metaprogramming
428431
include("meta.jl")
429432

base/task.jl

+14-2
Original file line numberDiff line numberDiff line change
@@ -928,7 +928,8 @@ function workqueue_for(tid::Int)
928928
if length(qs) < tid
929929
nt = Threads.maxthreadid()
930930
@assert tid <= nt
931-
global Workqueues = qs = copyto!(typeof(qs)(undef, length(qs) + nt - 1), qs)
931+
new_length = length(qs) + nt - 1
932+
global Workqueues = qs = copyto!(typeof(qs)(undef, new_length), qs)
932933
end
933934
if !isassigned(qs, tid)
934935
@inbounds qs[tid] = StickyWorkqueue()
@@ -1098,7 +1099,9 @@ end
10981099

10991100
function try_yieldto(undo)
11001101
try
1102+
# stop timer - add to global timer
11011103
ccall(:jl_switch, Cvoid, ())
1104+
# start timer
11021105
catch
11031106
undo(ccall(:jl_get_next_task, Ref{Task}, ()))
11041107
rethrow()
@@ -1170,8 +1173,17 @@ end
11701173

11711174
function wait()
11721175
GC.safepoint()
1173-
W = workqueue_for(Threads.threadid())
1176+
tid = Threads.threadid()
1177+
W = workqueue_for(tid)
1178+
t = time_ns()
11741179
poptask(W)
1180+
t = time_ns() - t
1181+
if isassigned(Workqueue_sched_times)
1182+
ts = Workqueue_sched_times[]
1183+
if tid <= length(ts) # TODO: Grow Workqueue_sched_times if needed, but needs to be threadsafe
1184+
ts[tid] += t
1185+
end
1186+
end
11751187
result = try_yieldto(ensure_rescheduled)
11761188
process_events()
11771189
# return when we come out of the queue

base/timing.jl

+29-12
Original file line numberDiff line numberDiff line change
@@ -196,8 +196,8 @@ function format_bytes(bytes; binary=true) # also used by InteractiveUtils
196196
end
197197
end
198198

199-
function time_print(io::IO, elapsedtime, bytes=0, gctime=0, allocs=0, lock_conflicts=0, compile_time=0, recompile_time=0, newline=false;
200-
msg::Union{String,Nothing}=nothing)
199+
function time_print(io::IO, elapsedtime, bytes=0, gctime=0, allocs=0, lock_conflicts=0, compile_time=0, recompile_time=0, wall_time_sched=0,
200+
newline=false; msg::Union{String,Nothing}=nothing)
201201
timestr = Ryu.writefixed(Float64(elapsedtime/1e9), 6)
202202
str = sprint() do io
203203
if msg isa String
@@ -223,12 +223,22 @@ function time_print(io::IO, elapsedtime, bytes=0, gctime=0, allocs=0, lock_confl
223223
end
224224
print(io, Ryu.writefixed(Float64(100*gctime/elapsedtime), 2), "% gc time")
225225
end
226+
wall_time_sched_perc = wall_time_sched / (elapsedtime / 1e9)
227+
if wall_time_sched_perc > 0.1
228+
if bytes != 0 || allocs != 0 || gctime > 0
229+
print(io, ", ")
230+
end
231+
print(io, Ryu.writefixed(Float64(100*wall_time_sched_perc), 2), "% wall time scheduling")
232+
end
226233
if lock_conflicts > 0
234+
if bytes != 0 || allocs != 0 || gctime > 0 || wall_time_sched_perc > 0.1
235+
print(io, ", ")
236+
end
227237
plural = lock_conflicts == 1 ? "" : "s"
228238
print(io, ", ", lock_conflicts, " lock conflict$plural")
229239
end
230240
if compile_time > 0
231-
if bytes != 0 || allocs != 0 || gctime > 0
241+
if bytes != 0 || allocs != 0 || gctime > 0 || wall_time_sched_perc > 0.1 || lock_conflicts > 0
232242
print(io, ", ")
233243
end
234244
print(io, Ryu.writefixed(Float64(100*compile_time/elapsedtime), 2), "% compilation time")
@@ -343,7 +353,7 @@ macro time(msg, ex)
343353
local ret = @timed $(esc(ex))
344354
local _msg = $(esc(msg))
345355
local _msg_str = _msg === nothing ? _msg : string(_msg)
346-
time_print(stdout, ret.time*1e9, ret.gcstats.allocd, ret.gcstats.total_time, gc_alloc_count(ret.gcstats), ret.lock_conflicts, ret.compile_time*1e9, ret.recompile_time*1e9, true; msg=_msg_str)
356+
time_print(stdout, ret.time*1e9, ret.gcstats.allocd, ret.gcstats.total_time, gc_alloc_count(ret.gcstats), ret.lock_conflicts, ret.compile_time*1e9, ret.recompile_time*1e9, ret.wall_time_sched, true; msg=_msg_str)
347357
ret.value
348358
end
349359
end
@@ -603,13 +613,19 @@ macro timed(ex)
603613
local elapsedtime = time_ns()
604614
cumulative_compile_timing(true)
605615
local compile_elapsedtimes = cumulative_compile_time_ns()
606-
local val = @__tryfinally($(esc(ex)),
607-
(elapsedtime = time_ns() - elapsedtime;
608-
cumulative_compile_timing(false);
609-
compile_elapsedtimes = cumulative_compile_time_ns() .- compile_elapsedtimes;
610-
lock_conflicts = Threads.LOCK_CONFLICT_COUNT[] - lock_conflicts;
611-
Threads.lock_profiling(false))
612-
)
616+
local wall_time_sched = 0.0
617+
ScopedValues.@with Workqueue_sched_times => zeros(UInt, Threads.maxthreadid()) begin
618+
sched_ts = copy(Base.Workqueue_sched_times[])
619+
local val = @__tryfinally($(esc(ex)),
620+
(elapsedtime = time_ns() - elapsedtime;
621+
cumulative_compile_timing(false);
622+
compile_elapsedtimes = cumulative_compile_time_ns() .- compile_elapsedtimes;
623+
lock_conflicts = Threads.LOCK_CONFLICT_COUNT[] - lock_conflicts;
624+
Threads.lock_profiling(false))
625+
)
626+
wall_time_sched = sum(Base.Workqueue_sched_times[] .- sched_ts) / (Threads.nthreads(:interactive) + Threads.nthreads(:default))
627+
end
628+
613629
local diff = GC_Diff(gc_num(), stats)
614630
(
615631
value=val,
@@ -619,7 +635,8 @@ macro timed(ex)
619635
gcstats=diff,
620636
lock_conflicts=lock_conflicts,
621637
compile_time=compile_elapsedtimes[1]/1e9,
622-
recompile_time=compile_elapsedtimes[2]/1e9
638+
recompile_time=compile_elapsedtimes[2]/1e9,
639+
wall_time_sched=wall_time_sched/1e9
623640
)
624641
end
625642
end

0 commit comments

Comments
 (0)