Skip to content

Commit 5bf5918

Browse files
committed
Add the Timers module to measure real-time and cpu-time
This code is based on the `google/benchmarks` repository. - `realtime` is a monotonic high-resolution clock provided by the kernel. In most cases this is equivalent to `time_ns` in `Base`. - `cputime` is the time that the process was actually running on a processor. This excludes time spend in the kernel and time spend descheduled. The `Timers` module includes a fair-amount of platform specific code so the implementation is split between a generic *unix* implementation based on the high-resoltion clocked provided through `clock_gettime`. On *darwin* prior to 10.12.0 the kernel only provides `CLOCK_MONOTONIC` making it less useful and we have to fallback onto `getRUsage`. We intentional don't do error handling for the timer calls. Which may or may not be a wise choice.
1 parent ef5bc08 commit 5bf5918

File tree

6 files changed

+191
-2
lines changed

6 files changed

+191
-2
lines changed

LICENSE.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
The BenchmarkTools.jl package is licensed under the MIT "Expat" License:
22

3-
> Copyright (c) 2015: Jarrett Revels.
3+
> Copyright (c) 2015-2018: Jarrett Revels and other contributors:
4+
> https://github.com/JuliaCI/BenchmarkTools.jl/contributors
45
>
56
> Permission is hereby granted, free of charge, to any person obtaining
67
> a copy of this software and associated documentation files (the

src/BenchmarkTools.jl

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@ end
1212

1313
const BENCHMARKTOOLS_VERSION = v"0.2.2"
1414

15+
##########
16+
# Timers #
17+
##########
18+
19+
include("timers/timers.jl")
20+
1521
##############
1622
# Parameters #
1723
##############
@@ -26,7 +32,9 @@ export loadparams!
2632

2733
include("trials.jl")
2834

29-
export gctime,
35+
export realtime,
36+
cputime,
37+
gctime,
3038
memory,
3139
allocs,
3240
params,

src/timers/darwin.jl

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
##
2+
# This file is a part of BenchmarkTools.jl. License is MIT
3+
#
4+
# Based upon https://github.com/google/benchmark, which is licensed under Apache v2:
5+
# https://github.com/google/benchmark/blob/master/LICENSE
6+
#
7+
# In compliance with the Apache v2 license, here are the original copyright notices:
8+
# Copyright 2015 Google Inc. All rights reserved.
9+
##
10+
11+
const RUSAGE_SELF = Cint(0)
12+
const RUSAGE_CHILDREN = Cint(-1)
13+
14+
struct TimeVal
15+
tv_sec::Clong
16+
tv_usec::Clong
17+
end
18+
19+
struct RUsage
20+
ru_utime::TimeVal
21+
ru_stime::TimeVal
22+
ru_maxrss::Clong
23+
ru_ixrss::Clong
24+
ru_idrss::Clong
25+
ru_isrss::Clong
26+
ru_minflt::Clong
27+
ru_majflt::Clong
28+
ru_nswap::Clong
29+
ru_inblock::Clong
30+
ru_outblock::Clong
31+
ru_msgsnd::Clong
32+
ru_msgrcv::Clong
33+
ru_nsignals::Clong
34+
ru_nvcsw::Clong
35+
ru_nivcsw::Clong
36+
end
37+
38+
@inline function maketime(ru::RUsage)
39+
user = ru.ru_utime.tv_sec * 1e9 + ru.ru_utime.tv_usec *1e3
40+
kernel = ru.ru_stime.tv_sec * 1e9 + ru.ru_stime.tv_usec *1e3
41+
return user+kernel
42+
end
43+
44+
@inline function realtime()
45+
Float64(Base.time_ns())
46+
end
47+
48+
@inline function cputime()
49+
ru = Ref{RUsage}()
50+
ccall(:getRUsage, Cint, (Cint, Ref{RUsage}), RUSAGE_SELF, ru)
51+
return maketime(ru[])
52+
end

src/timers/timers.jl

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# This file is a part of BenchmarkTools.jl. License is MIT
2+
3+
module Timers
4+
import Compat
5+
6+
"""
7+
realtime()
8+
9+
Monotonic runtime counter
10+
11+
Returns time in ns as Float64.
12+
"""
13+
function realtime end
14+
15+
"""
16+
cputime()
17+
18+
Process specific CPU time clock.
19+
20+
Returns time in ns as Float64.
21+
"""
22+
function cputime end
23+
24+
function _applever()
25+
return VersionNumber(readchomp(`sw_vers -productVersion`))
26+
end
27+
28+
if Compat.Sys.isapple() && _applever() < v"10.12.0"
29+
include("darwin.jl")
30+
elseif Compat.Sys.isunix()
31+
include("unix.jl")
32+
elseif Compat.Sys.iswindows()
33+
include("windows.jl")
34+
else
35+
error("$(Sys.KERNEL) is not supported please file an issue")
36+
end
37+
end # module

src/timers/unix.jl

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
##
2+
# This file is a part of BenchmarkTools.jl. License is MIT
3+
#
4+
# Based upon https://github.com/google/benchmark, which is licensed under Apache v2:
5+
# https://github.com/google/benchmark/blob/master/LICENSE
6+
#
7+
# In compliance with the Apache v2 license, here are the original copyright notices:
8+
# Copyright 2015 Google Inc. All rights reserved.
9+
##
10+
11+
struct TimeSpec
12+
tv_sec :: UInt64 # time_t
13+
tv_nsec :: UInt64
14+
end
15+
16+
maketime(ts) = ts.tv_sec * 1e9 + ts.tv_nsec
17+
18+
# From bits/times.h on a Linux system
19+
# Check if those are the same on BSD
20+
if Compat.Sys.islinux()
21+
const CLOCK_MONOTONIC = Cint(1)
22+
const CLOCK_PROCESS_CPUTIME_ID = Cint(2)
23+
elseif Sys.KERNEL == :FreeBSD # atleast on FreeBSD 11.1
24+
const CLOCK_MONOTONIC = Cint(4)
25+
const CLOCK_PROCESS_CPUTIME_ID = Cint(14)
26+
elseif Compat.Sys.isapple() # Version 10.12 required
27+
const CLOCK_MONOTONIC = Cint(6)
28+
const CLOCK_PROCESS_CPUTIME_ID = Cint(12)
29+
else
30+
error("""
31+
BenchmarkTools doesn't currently support your operating system.
32+
Please file an issue, your kernel is $(Sys.KERNEL)
33+
""")
34+
end
35+
36+
@inline function clock_gettime(cid)
37+
ts = Ref{TimeSpec}()
38+
ccall(:clock_gettime, Cint, (Cint, Ref{TimeSpec}), cid, ts)
39+
return ts[]
40+
end
41+
42+
@inline function realtime()
43+
maketime(clock_gettime(CLOCK_MONOTONIC))
44+
end
45+
46+
@inline function cputime()
47+
maketime(clock_gettime(CLOCK_PROCESS_CPUTIME_ID))
48+
end

src/timers/windows.jl

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
##
2+
# This file is a part of BenchmarkTools.jl. License is MIT
3+
#
4+
# Based upon https://github.com/google/benchmark, which is licensed under Apache v2:
5+
# https://github.com/google/benchmark/blob/master/LICENSE
6+
#
7+
# In compliance with the Apache v2 license, here are the original copyright notices:
8+
# Copyright 2015 Google Inc. All rights reserved.
9+
##
10+
11+
"""
12+
FileTime
13+
14+
See https://msdn.microsoft.com/en-us/library/windows/desktop/ms724284(v=vs.85).aspx
15+
"""
16+
struct FileTime
17+
dwHighDateTime::UInt32
18+
dwLowDateTime::UInt32
19+
end
20+
21+
const HANDLE = Ptr{Void}
22+
23+
@inline function maketime(kernel_time::FileTime, user_time::FileTime)
24+
kernel = (kernel_time.dwHighDateTime % UInt64) << 32 | kernel_time.dwLowDateTime
25+
user = ( user_time.dwHighDateTime % UInt64) << 32 | user_time.dwLowDateTime
26+
(kernel + user) * 1e2
27+
end
28+
29+
@inline function realtime()
30+
return Float64(Base.time_ns())
31+
end
32+
33+
@inline function cputime()
34+
proc = ccall(:GetCurrentProcess, HANDLE, ())
35+
creation_time = Ref{FileTime}()
36+
exit_time = Ref{FileTime}()
37+
kernel_time = Ref{FileTime}()
38+
user_time = Ref{FileTime}()
39+
40+
ccall(:GetProccessTimes, Cint, (HANDLE, Ref{FileTime}, Ref{FileTime}, Ref{FileTime}, Ref{FileTime}),
41+
proc, creation_time, exit_time, kernel_time, user_time)
42+
return maketime(kernel_time, user_time)
43+
end

0 commit comments

Comments
 (0)