Skip to content

Commit f64f02b

Browse files
authored
Merge pull request #20212 from palimondo/fluctuation-of-the-pupil
[benchmark] Legacy Factor
2 parents fcff56d + f121ee1 commit f64f02b

File tree

8 files changed

+44
-30
lines changed

8 files changed

+44
-30
lines changed

benchmark/scripts/Benchmark_Driver

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,7 @@ class BenchmarkDoctor(object):
343343
setup, ratio = BenchmarkDoctor._setup_overhead(measurements)
344344
setup = 0 if ratio < 0.05 else setup
345345
runtime = min(
346-
[(result.min - correction) for i_series in
346+
[(result.samples.min - correction) for i_series in
347347
[BenchmarkDoctor._select(measurements, num_iters=i)
348348
for correction in [(setup / i) for i in [1, 2]]
349349
] for result in i_series])
@@ -367,7 +367,8 @@ class BenchmarkDoctor(object):
367367
def _setup_overhead(measurements):
368368
select = BenchmarkDoctor._select
369369
ti1, ti2 = [float(min(mins)) for mins in
370-
[[result.min for result in i_series] for i_series in
370+
[[result.samples.min for result in i_series]
371+
for i_series in
371372
[select(measurements, num_iters=i) for i in [1, 2]]]]
372373
setup = int(round(2.0 * (ti1 - ti2)))
373374
ratio = (setup / ti1) if ti1 > 0 else 0
@@ -439,8 +440,9 @@ class BenchmarkDoctor(object):
439440
Returns a dictionary with benchmark name and `PerformanceTestResult`s.
440441
"""
441442
self.log.debug('Calibrating num-samples for {0}:'.format(benchmark))
442-
r = self.driver.run(benchmark, num_samples=3, num_iters=1) # calibrate
443-
num_samples = self._adjusted_1s_samples(r.min)
443+
r = self.driver.run(benchmark, num_samples=3, num_iters=1,
444+
verbose=True) # calibrate
445+
num_samples = self._adjusted_1s_samples(r.samples.min)
444446

445447
def capped(s):
446448
return min(s, 2048)
@@ -449,7 +451,7 @@ class BenchmarkDoctor(object):
449451
opts = opts if isinstance(opts, list) else [opts]
450452
self.log.debug(
451453
'Runtime {0} μs yields {1} adjusted samples per second.'.format(
452-
r.min, num_samples))
454+
r.samples.min, num_samples))
453455
self.log.debug(
454456
'Measuring {0}, 5 x i1 ({1} samples), 5 x i2 ({2} samples)'.format(
455457
benchmark, run_args[0][0], run_args[1][0]))

benchmark/scripts/test_Benchmark_Driver.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -423,7 +423,7 @@ def test_no_prefix_for_base_logging(self):
423423

424424
def _PTR(min=700, mem_pages=1000, setup=None):
425425
"""Create PerformanceTestResult Stub."""
426-
return Stub(min=min, mem_pages=mem_pages, setup=setup)
426+
return Stub(samples=Stub(min=min), mem_pages=mem_pages, setup=setup)
427427

428428

429429
def _run(test, num_samples=None, num_iters=None, verbose=None,
@@ -483,7 +483,8 @@ def test_measure_10_independent_1s_benchmark_series(self):
483483
"""
484484
driver = BenchmarkDriverMock(tests=['B1'], responses=([
485485
# calibration run, returns a stand-in for PerformanceTestResult
486-
(_run('B1', num_samples=3, num_iters=1), _PTR(min=300))] +
486+
(_run('B1', num_samples=3, num_iters=1,
487+
verbose=True), _PTR(min=300))] +
487488
# 5x i1 series, with 300 μs runtime its possible to take 4098
488489
# samples/s, but it should be capped at 2k
489490
([(_run('B1', num_samples=2048, num_iters=1,

benchmark/single-source/AnyHashableWithAClass.swift

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,12 @@ import TestsUtils
2525
public var AnyHashableWithAClass = BenchmarkInfo(
2626
name: "AnyHashableWithAClass",
2727
runFunction: run_AnyHashableWithAClass,
28-
tags: [.abstraction, .runtime, .cpubench]
28+
tags: [.abstraction, .runtime, .cpubench],
29+
legacyFactor: lf
2930
)
3031

32+
let lf = 500
33+
3134
class TestHashableBase : Hashable {
3235
var value: Int
3336
init(_ value: Int) {
@@ -55,8 +58,7 @@ class TestHashableDerived5 : TestHashableDerived4 {}
5558
@inline(never)
5659
public func run_AnyHashableWithAClass(_ N: Int) {
5760
let c = TestHashableDerived5(10)
58-
for _ in 0...(N*500000) {
61+
for _ in 0...(N*500000/lf) {
5962
_ = AnyHashable(c)
6063
}
6164
}
62-

benchmark/single-source/ArrayOfGenericRef.swift

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,15 @@
1313
// This benchmark tests creation and destruction of an array of enum
1414
// and generic type bound to nontrivial types.
1515
//
16-
// For comparison, we always create three arrays of 10,000 words.
16+
// For comparison, we always create three arrays of 1,000 words.
1717

1818
import TestsUtils
1919

2020
public let ArrayOfGenericRef = BenchmarkInfo(
2121
name: "ArrayOfGenericRef",
2222
runFunction: run_ArrayOfGenericRef,
23-
tags: [.validation, .api, .Array])
23+
tags: [.validation, .api, .Array],
24+
legacyFactor: 10)
2425

2526
protocol Constructible {
2627
associatedtype Element
@@ -31,8 +32,8 @@ class ConstructibleArray<T:Constructible> {
3132

3233
init(_ e:T.Element) {
3334
array = [T]()
34-
array.reserveCapacity(10_000)
35-
for _ in 0...10_000 {
35+
array.reserveCapacity(1_000)
36+
for _ in 0...1_000 {
3637
array.append(T(e:e) as T)
3738
}
3839
}
@@ -65,7 +66,7 @@ func genCommonRefArray() {
6566
class RefArray<T> {
6667
var array: [T]
6768

68-
init(_ i:T, count:Int = 10_000) {
69+
init(_ i:T, count:Int = 1_000) {
6970
array = [T](repeating: i, count: count)
7071
}
7172
}

benchmark/single-source/ArrayOfRef.swift

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,15 @@
1414
// references. It is meant to be a baseline for comparison against
1515
// ArrayOfGenericRef.
1616
//
17-
// For comparison, we always create four arrays of 10,000 words.
17+
// For comparison, we always create four arrays of 1,000 words.
1818

1919
import TestsUtils
2020

2121
public let ArrayOfRef = BenchmarkInfo(
2222
name: "ArrayOfRef",
2323
runFunction: run_ArrayOfRef,
24-
tags: [.validation, .api, .Array])
24+
tags: [.validation, .api, .Array],
25+
legacyFactor: 10)
2526

2627
protocol Constructible {
2728
associatedtype Element
@@ -32,8 +33,8 @@ class ConstructibleArray<T:Constructible> {
3233

3334
init(_ e:T.Element) {
3435
array = [T]()
35-
array.reserveCapacity(10_000)
36-
for _ in 0...10_000 {
36+
array.reserveCapacity(1_000)
37+
for _ in 0...1_000 {
3738
array.append(T(e:e) as T)
3839
}
3940
}
@@ -77,7 +78,7 @@ enum RefEnum {
7778
class RefArray<T> {
7879
var array : [T]
7980

80-
init(_ i:T, count:Int = 10_000) {
81+
init(_ i:T, count:Int = 1_000) {
8182
array = [T](repeating: i, count: count)
8283
}
8384
}

benchmark/single-source/ArraySetElement.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ import TestsUtils
1818
public var ArraySetElement = BenchmarkInfo(
1919
name: "ArraySetElement",
2020
runFunction: run_ArraySetElement,
21-
tags: [.runtime, .cpubench, .unstable]
21+
tags: [.runtime, .cpubench, .unstable],
22+
legacyFactor: 10
2223
)
2324

2425
// This is an effort to defeat isUniquelyReferenced optimization. Ideally
@@ -29,9 +30,8 @@ func storeArrayElement(_ array: inout [Int], _ i: Int) {
2930
}
3031

3132
public func run_ArraySetElement(_ N: Int) {
32-
let scale = 10
3333
var array = [Int](repeating: 0, count: 10000)
34-
for _ in 0..<N*scale {
34+
for _ in 0..<N {
3535
for i in 0..<array.count {
3636
storeArrayElement(&array, i)
3737
}

benchmark/utils/DriverUtils.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,10 @@ final class TestRunner {
524524
}
525525

526526
test.tearDownFunction?()
527+
if let lf = test.legacyFactor {
528+
logVerbose(" Applying legacy factor: \(lf)")
529+
samples = samples.map { $0 * lf }
530+
}
527531

528532
return BenchResults(samples, maxRSS: measureMemoryUsage())
529533
}

benchmark/utils/TestsUtils.swift

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,18 @@ public enum BenchmarkCategory : String {
2626
case runtime, refcount, metadata
2727
// Other general areas of compiled code validation.
2828
case abstraction, safetychecks, exceptions, bridging, concurrency
29-
29+
3030
// Algorithms are "micro" that test some well-known algorithm in isolation:
3131
// sorting, searching, hashing, fibonaci, crypto, etc.
3232
case algorithm
33-
33+
3434
// Miniapplications are contrived to mimic some subset of application behavior
3535
// in a way that can be easily measured. They are larger than micro-benchmarks,
3636
// combining multiple APIs, data structures, or algorithms. This includes small
3737
// standardized benchmarks, pieces of real applications that have been extracted
3838
// into a benchmark, important functionality like JSON parsing, etc.
3939
case miniapplication
40-
40+
4141
// Regression benchmarks is a catch-all for less important "micro"
4242
// benchmarks. This could be a random piece of code that was attached to a bug
4343
// report. We want to make sure the optimizer as a whole continues to handle
@@ -46,12 +46,12 @@ public enum BenchmarkCategory : String {
4646
// as highly as "validation" benchmarks and likely won't be the subject of
4747
// future investigation unless they significantly regress.
4848
case regression
49-
49+
5050
// Most benchmarks are assumed to be "stable" and will be regularly tracked at
5151
// each commit. A handful may be marked unstable if continually tracking them is
5252
// counterproductive.
5353
case unstable
54-
54+
5555
// CPU benchmarks represent instrinsic Swift performance. They are useful for
5656
// measuring a fully baked Swift implementation across different platforms and
5757
// hardware. The benchmark should also be reasonably applicable to real Swift
@@ -151,16 +151,20 @@ public struct BenchmarkInfo {
151151
return _tearDownFunction
152152
}
153153

154+
public var legacyFactor: Int?
155+
154156
public init(name: String, runFunction: @escaping (Int) -> (), tags: [BenchmarkCategory],
155157
setUpFunction: (() -> ())? = nil,
156158
tearDownFunction: (() -> ())? = nil,
157-
unsupportedPlatforms: BenchmarkPlatformSet = []) {
159+
unsupportedPlatforms: BenchmarkPlatformSet = [],
160+
legacyFactor: Int? = nil) {
158161
self.name = name
159162
self._runFunction = runFunction
160163
self.tags = Set(tags)
161164
self._setUpFunction = setUpFunction
162165
self._tearDownFunction = tearDownFunction
163166
self.unsupportedPlatforms = unsupportedPlatforms
167+
self.legacyFactor = legacyFactor
164168
}
165169

166170
/// Returns true if this benchmark should be run on the current platform.
@@ -266,4 +270,3 @@ public func getString(_ s: String) -> String { return s }
266270
// The same for Substring.
267271
@inline(never)
268272
public func getSubstring(_ s: Substring) -> Substring { return s }
269-

0 commit comments

Comments
 (0)