@@ -247,7 +247,7 @@ func stopTrackingObjects(_: UnsafePointer<CChar>) -> Int
247
247
#endif
248
248
249
249
#if os(Linux)
250
- class Timer {
250
+ final class Timer {
251
251
typealias TimeT = timespec
252
252
func getTime( ) -> TimeT {
253
253
var ticks = timespec ( tv_sec: 0 , tv_nsec: 0 )
@@ -267,7 +267,7 @@ class Timer {
267
267
}
268
268
}
269
269
#else
270
- class Timer {
270
+ final class Timer {
271
271
typealias TimeT = UInt64
272
272
var info = mach_timebase_info_data_t ( numer: 0 , denom: 0 )
273
273
init ( ) {
@@ -283,13 +283,18 @@ class Timer {
283
283
}
284
284
#endif
285
285
286
- class SampleRunner {
286
+ final class SampleRunner {
287
287
let timer = Timer ( )
288
288
let baseline = SampleRunner . getResourceUtilization ( )
289
289
let c : TestConfig
290
+ var start , end , lastYield : Timer . TimeT
291
+ let schedulerQuantum = UInt64 ( 10_000_000 ) // nanoseconds (== 10ms, macos)
290
292
291
293
init ( _ config: TestConfig ) {
292
294
self . c = config
295
+ sched_yield ( )
296
+ let now = timer. getTime ( )
297
+ ( start, end, lastYield) = ( now, now, now)
293
298
}
294
299
295
300
private static func getResourceUtilization( ) -> rusage {
@@ -298,39 +303,63 @@ class SampleRunner {
298
303
299
304
/// Returns maximum resident set size (MAX_RSS) delta in bytes
300
305
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
303
308
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) "
315
314
}
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)
317
347
}
318
348
319
349
func run( _ name: String , fn: ( Int ) -> Void , num_iters: UInt ) -> UInt64 {
320
- // Start the timer.
321
350
#if SWIFT_RUNTIME_ENABLE_LEAK_CHECKER
322
351
name. withCString { p in startTrackingObjects ( p) }
323
352
#endif
324
- let start_ticks = timer. getTime ( )
353
+
354
+ self . startMeasurement ( )
325
355
fn ( Int ( num_iters) )
326
- // Stop the timer.
327
- let end_ticks = timer . getTime ( )
356
+ self . stopMeasurement ( )
357
+
328
358
#if SWIFT_RUNTIME_ENABLE_LEAK_CHECKER
329
359
name. withCString { p in stopTrackingObjects ( p) }
330
360
#endif
331
361
332
- // Compute the spent time and the scaling factor.
333
- return timer. diffTimeInNanoSeconds ( from: start_ticks, to: end_ticks)
362
+ return lastSampleTime
334
363
}
335
364
}
336
365
0 commit comments