Skip to content

Commit 10468c6

Browse files
authored
Merge pull request swiftlang#19011 from palimondo/fluctuation-of-the-pupil
[benchmark] Yield when time slice expires
2 parents d2413dd + b482a04 commit 10468c6

File tree

1 file changed

+52
-23
lines changed

1 file changed

+52
-23
lines changed

benchmark/utils/DriverUtils.swift

Lines changed: 52 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ func stopTrackingObjects(_: UnsafePointer<CChar>) -> Int
247247
#endif
248248

249249
#if os(Linux)
250-
class Timer {
250+
final class Timer {
251251
typealias TimeT = timespec
252252
func getTime() -> TimeT {
253253
var ticks = timespec(tv_sec: 0, tv_nsec: 0)
@@ -267,7 +267,7 @@ class Timer {
267267
}
268268
}
269269
#else
270-
class Timer {
270+
final class Timer {
271271
typealias TimeT = UInt64
272272
var info = mach_timebase_info_data_t(numer: 0, denom: 0)
273273
init() {
@@ -283,13 +283,18 @@ class Timer {
283283
}
284284
#endif
285285

286-
class SampleRunner {
286+
final class SampleRunner {
287287
let timer = Timer()
288288
let baseline = SampleRunner.getResourceUtilization()
289289
let c: TestConfig
290+
var start, end, lastYield: Timer.TimeT
291+
let schedulerQuantum = UInt64(10_000_000) // nanoseconds (== 10ms, macos)
290292

291293
init(_ config: TestConfig) {
292294
self.c = config
295+
sched_yield()
296+
let now = timer.getTime()
297+
(start, end, lastYield) = (now, now, now)
293298
}
294299

295300
private static func getResourceUtilization() -> rusage {
@@ -298,39 +303,63 @@ class SampleRunner {
298303

299304
/// Returns maximum resident set size (MAX_RSS) delta in bytes
300305
func measureMemoryUsage() -> Int {
301-
var current = SampleRunner.getResourceUtilization()
302-
let maxRSS = current.ru_maxrss - baseline.ru_maxrss
306+
let current = SampleRunner.getResourceUtilization()
307+
let maxRSS = current.ru_maxrss - baseline.ru_maxrss
303308

304-
if c.verbose {
305-
let pages = maxRSS / sysconf(_SC_PAGESIZE)
306-
func deltaEquation(_ stat: KeyPath<rusage, Int>) -> String {
307-
let b = baseline[keyPath: stat], c = current[keyPath: stat]
308-
return "\(c) - \(b) = \(c - b)"
309-
}
310-
print("""
311-
MAX_RSS \(deltaEquation(\rusage.ru_maxrss)) (\(pages) pages)
312-
ICS \(deltaEquation(\rusage.ru_nivcsw))
313-
VCS \(deltaEquation(\rusage.ru_nvcsw))
314-
""")
309+
if c.verbose {
310+
let pages = maxRSS / sysconf(_SC_PAGESIZE)
311+
func deltaEquation(_ stat: KeyPath<rusage, Int>) -> String {
312+
let b = baseline[keyPath: stat], c = current[keyPath: stat]
313+
return "\(c) - \(b) = \(c - b)"
315314
}
316-
return maxRSS
315+
print("""
316+
MAX_RSS \(deltaEquation(\rusage.ru_maxrss)) (\(pages) pages)
317+
ICS \(deltaEquation(\rusage.ru_nivcsw))
318+
VCS \(deltaEquation(\rusage.ru_nvcsw))
319+
""")
320+
}
321+
return maxRSS
322+
}
323+
324+
private func startMeasurement() {
325+
let spent = timer.diffTimeInNanoSeconds(from: lastYield, to: end)
326+
let nextSampleEstimate = UInt64(Double(lastSampleTime) * 1.5)
327+
328+
if (spent + nextSampleEstimate < schedulerQuantum) {
329+
start = timer.getTime()
330+
} else {
331+
if c.verbose {
332+
print(" Yielding again after estimated \(spent/1000) us")
333+
}
334+
sched_yield()
335+
let now = timer.getTime()
336+
(start, lastYield) = (now, now)
337+
}
338+
}
339+
340+
private func stopMeasurement() {
341+
end = timer.getTime()
342+
}
343+
344+
/// Time in nanoseconds spent running the last function
345+
var lastSampleTime: UInt64 {
346+
return timer.diffTimeInNanoSeconds(from: start, to: end)
317347
}
318348

319349
func run(_ name: String, fn: (Int) -> Void, num_iters: UInt) -> UInt64 {
320-
// Start the timer.
321350
#if SWIFT_RUNTIME_ENABLE_LEAK_CHECKER
322351
name.withCString { p in startTrackingObjects(p) }
323352
#endif
324-
let start_ticks = timer.getTime()
353+
354+
self.startMeasurement()
325355
fn(Int(num_iters))
326-
// Stop the timer.
327-
let end_ticks = timer.getTime()
356+
self.stopMeasurement()
357+
328358
#if SWIFT_RUNTIME_ENABLE_LEAK_CHECKER
329359
name.withCString { p in stopTrackingObjects(p) }
330360
#endif
331361

332-
// Compute the spent time and the scaling factor.
333-
return timer.diffTimeInNanoSeconds(from: start_ticks, to: end_ticks)
362+
return lastSampleTime
334363
}
335364
}
336365

0 commit comments

Comments
 (0)