Skip to content

Commit 5f8209e

Browse files
authored
Merge pull request #16872 from gottesmm/pr-6ca8783e222690b6bd1095fa5c8eac02efb5f0fe
[benchmark] Add the ability for a benchmark to specify that it does n…
2 parents dca28f0 + 45b7743 commit 5f8209e

File tree

2 files changed

+83
-12
lines changed

2 files changed

+83
-12
lines changed

benchmark/utils/DriverUtils.swift

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ struct Test {
6363
}
6464

6565
/// The "main routine" of the benchmark.
66-
var runFunction: (Int) -> () {
66+
var runFunction: ((Int) -> ())? {
6767
return benchInfo.runFunction
6868
}
6969

@@ -358,9 +358,19 @@ class SampleRunner {
358358
}
359359

360360
/// Invoke the benchmark entry point and return the run time in milliseconds.
361-
func runBench(_ test: Test, _ c: TestConfig) -> BenchResults {
361+
func runBench(_ test: Test, _ c: TestConfig) -> BenchResults? {
362362
var samples = [UInt64](repeating: 0, count: c.numSamples)
363363

364+
// Before we do anything, check that we actually have a function to
365+
// run. If we don't it is because the benchmark is not supported on
366+
// the platform and we should skip it.
367+
guard let testFn = test.runFunction else {
368+
if c.verbose {
369+
print("Skipping unsupported benchmark \(test.name)!")
370+
}
371+
return nil
372+
}
373+
364374
if c.verbose {
365375
print("Running \(test.name) for \(c.numSamples) samples.")
366376
}
@@ -373,7 +383,7 @@ func runBench(_ test: Test, _ c: TestConfig) -> BenchResults {
373383
var elapsed_time : UInt64 = 0
374384
if c.fixedNumIters == 0 {
375385
test.setUpFunction?()
376-
elapsed_time = sampler.run(test.name, fn: test.runFunction, num_iters: 1)
386+
elapsed_time = sampler.run(test.name, fn: testFn, num_iters: 1)
377387
test.tearDownFunction?()
378388

379389
if elapsed_time > 0 {
@@ -395,7 +405,7 @@ func runBench(_ test: Test, _ c: TestConfig) -> BenchResults {
395405
print(" Measuring with scale \(scale).")
396406
}
397407
test.setUpFunction?()
398-
elapsed_time = sampler.run(test.name, fn: test.runFunction, num_iters: scale)
408+
elapsed_time = sampler.run(test.name, fn: testFn, num_iters: scale)
399409
test.tearDownFunction?()
400410
} else {
401411
scale = 1
@@ -442,7 +452,11 @@ func runBenchmarks(_ c: TestConfig) {
442452
sumBenchResults.sampleCount = 0
443453

444454
for t in c.tests {
445-
let results = runBench(t, c)
455+
guard let results = runBench(t, c) else {
456+
print("\(t.index)\(c.delim)\(t.name)\(c.delim)Unsupported")
457+
fflush(stdout)
458+
continue
459+
}
446460
print("\(t.index)\(c.delim)\(t.name)\(c.delim)\(results.description)")
447461
fflush(stdout)
448462

benchmark/utils/TestsUtils.swift

Lines changed: 64 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -70,34 +70,91 @@ public enum BenchmarkCategory : String {
7070
case skip
7171
}
7272

73+
public struct BenchmarkPlatformSet : OptionSet {
74+
public let rawValue: Int
75+
76+
public init(rawValue: Int) {
77+
self.rawValue = rawValue
78+
}
79+
80+
public static let darwin = BenchmarkPlatformSet(rawValue: 1 << 0)
81+
public static let linux = BenchmarkPlatformSet(rawValue: 1 << 1)
82+
83+
public static var currentPlatform: BenchmarkPlatformSet {
84+
#if os(Linux)
85+
return .linux
86+
#else
87+
return .darwin
88+
#endif
89+
}
90+
91+
public static var allPlatforms: BenchmarkPlatformSet {
92+
return [.darwin, .linux]
93+
}
94+
}
95+
7396
public struct BenchmarkInfo {
7497
/// The name of the benchmark that should be displayed by the harness.
7598
public var name: String
7699

100+
/// Shadow static variable for runFunction.
101+
private var _runFunction: (Int) -> ()
102+
77103
/// A function that invokes the specific benchmark routine.
78-
public var runFunction: (Int) -> ()
104+
public var runFunction: ((Int) -> ())? {
105+
if !shouldRun {
106+
return nil
107+
}
108+
return _runFunction
109+
}
79110

80111
/// A set of category tags that describe this benchmark. This is used by the
81112
/// harness to allow for easy slicing of the set of benchmarks along tag
82113
/// boundaries, e.x.: run all string benchmarks or ref count benchmarks, etc.
83114
public var tags: [BenchmarkCategory]
84115

116+
/// The platforms that this benchmark supports. This is an OptionSet.
117+
private var unsupportedPlatforms: BenchmarkPlatformSet
118+
119+
/// Shadow variable for setUpFunction.
120+
private var _setUpFunction: (() -> ())?
121+
85122
/// An optional function that if non-null is run before benchmark samples
86123
/// are timed.
87-
public var setUpFunction: (() -> ())?
124+
public var setUpFunction : (() -> ())? {
125+
if !shouldRun {
126+
return nil
127+
}
128+
return _setUpFunction
129+
}
130+
131+
/// Shadow static variable for computed property tearDownFunction.
132+
private var _tearDownFunction: (() -> ())?
88133

89134
/// An optional function that if non-null is run immediately after a sample is
90135
/// taken.
91-
public var tearDownFunction: (() -> ())?
136+
public var tearDownFunction: (() -> ())? {
137+
if !shouldRun {
138+
return nil
139+
}
140+
return _tearDownFunction
141+
}
92142

93143
public init(name: String, runFunction: @escaping (Int) -> (), tags: [BenchmarkCategory],
94144
setUpFunction: (() -> ())? = nil,
95-
tearDownFunction: (() -> ())? = nil) {
145+
tearDownFunction: (() -> ())? = nil,
146+
unsupportedPlatforms: BenchmarkPlatformSet = []) {
96147
self.name = name
97-
self.runFunction = runFunction
148+
self._runFunction = runFunction
98149
self.tags = tags
99-
self.setUpFunction = setUpFunction
100-
self.tearDownFunction = tearDownFunction
150+
self._setUpFunction = setUpFunction
151+
self._tearDownFunction = tearDownFunction
152+
self.unsupportedPlatforms = unsupportedPlatforms
153+
}
154+
155+
/// Returns true if this benchmark should be run on the current platform.
156+
var shouldRun: Bool {
157+
return !unsupportedPlatforms.contains(.currentPlatform)
101158
}
102159
}
103160

0 commit comments

Comments
 (0)