1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 /*
17 This file was generated by VMB using these parameters:
18
19 Benchmarks Class: $state_name
20 Bench Setup: $state_setup
21 Bench Method: $method_name -> $method_rettype
22 Parameter Set: #$fix_id $fixture
23 Bench Full Name: $bench_name
24 WarmUp Iterations: $wi
25 Measure Iterations: $mi
26 Iteration Time (sec): $it
27 Warmup Time (sec): $wt
28 Fast Iterations: $fi
29 */
30
31 $imports
32
33 // params
34 let WI: Int = $wi;
35 let MI: Int = $mi;
36 let IT: Int = $it;
37 let WT: Int = $wt;
38 let FI: Int = $fi;
39
40 let MAX_LOOP_COUNT = 10_000_000_000
41 var totalOps: Int = 0
42 var totalSec: Double = 0.0
43 var iter: Int = 1
44 var loopCount1: Int = 1
45
46 enum ConsumerError: Error {
47 case unexpectedResult
48 }
49
50 class Consumer {
51 static private let x1: Int64 = 0x41c64e6d
52 static private let x2: Int64 = 0xd431
53 static private var x3: Int64 = 1
54 static var boola: Bool = false
55 static var boolb: Bool = true
56 static var chara: Character = "X" // 16-bit
57 static var charb: Character = "Y"
58 static var bytea: Int8 = 24
59 static var byteb: Int8 = 53
60 static var shorta: Int16 = 24
61 static var shortb: Int16 = 53
62 static var inta: Int = 24
63 static var intb: Int = 53
64 static var longa: Int64 = 24
65 static var longb: Int64 = 53
66 static var floata: Float = 24.0
67 static var floatb: Float = 53.0
68 static var doublea: Double = 24.0
69 static var doubleb: Double = 53.0
70 static var pseudorand: Int64 = Int64.random(in: 1..<1_000_000)
71 static var localObj: AnyObject? = nil
72 static var localObjs: [AnyObject] = []
73
consumeBoolnull74 class func consumeBool(_ v: Bool) throws {
75 if (v == boola && v == boolb) {
76 throw ConsumerError.unexpectedResult
77 }
78 }
79
consumeCharnull80 class func consumeChar(_ v: Character) throws {
81 if (v == chara && v == charb) {
82 throw ConsumerError.unexpectedResult
83 }
84 }
85
consumeShortnull86 class func consumeShort(_ v: Int16) throws {
87 if (v == shorta && v == shortb) {
88 throw ConsumerError.unexpectedResult
89 }
90 }
91
consumeIntnull92 class func consumeInt(_ v: Int) throws {
93 if (v == inta && v == intb) {
94 throw ConsumerError.unexpectedResult
95 }
96 }
97
consumeLongnull98 class func consumeLong(_ v: Int64) throws {
99 if (v == longa && v == longb) {
100 throw ConsumerError.unexpectedResult
101 }
102 }
103
consumeFloatnull104 class func consumeFloat(_ v: Float) throws {
105 if (v == floata && v == floatb) {
106 throw ConsumerError.unexpectedResult
107 }
108 }
109
consumeDoublenull110 class func consumeDouble(_ v: Double) throws {
111 if (v == doublea && v == doubleb) {
112 throw ConsumerError.unexpectedResult
113 }
114 }
115
consumeObjnull116 class func consumeObj(_ v: AnyObject) {
117 // NOTE: these lines ported from other langs
118 // cause compiled binary to crash
119 // pseudorand = (pseudorand * x1 + x2)
120 // if ((pseudorand & x3) == 0) {
121 // x3 = (x3 << 1) + 0xad
122 // localObj = v
123 // }
124 if (pseudorand > x3) {
125 localObj = v
126 }
127 }
128
consumeObjsnull129 class func consumeObjs(_ v: [AnyObject]) {
130 if (pseudorand > x3) {
131 localObjs = v
132 }
133 }
134
consumenull135 class func consume(_ v: Bool) throws {
136 try consumeBool(v)
137 }
138
consumenull139 class func consume(_ v: Character) throws {
140 try consumeChar(v)
141 }
142
consumenull143 class func consume(_ v: Int16) throws {
144 try consumeShort(v)
145 }
146
consumenull147 class func consume(_ v: Int) throws {
148 try consumeInt(v)
149 }
150
consumenull151 class func consume(_ v: Int64) throws {
152 try consumeLong(v)
153 }
154
consumenull155 class func consume(_ v: Float) throws {
156 try consumeFloat(v)
157 }
158
consumenull159 class func consume(_ v: Double) throws {
160 try consumeDouble(v)
161 }
162
163 }
164
165 extension Duration {
166 var toDouble: Double {
167 return Double(components.seconds) + Double(components.attoseconds) * 1e-18
168 }
169 }
170
171 $common
172
173 $src
174
175 // no Foundation, so no Date()
176 print("Startup execution started: 0")
177
178 let clock = ContinuousClock()
179 let bench = $state_name()
180 $state_params
181 $state_setup
182
tunenull183 func tune() throws {
184 var secPerLoop: Double = 0.0
185 var loopCount: Int = 1
186 while (secPerLoop < 1.0 && loopCount < MAX_LOOP_COUNT) {
187 loopCount = loopCount * 2
188 secPerLoop = try clock.measure {
189 for _ in 0..<loopCount {
190 $method_call
191 }
192 }.toDouble
193 }
194 if (secPerLoop < 1.0) {
195 print("ERROR: Tuning Failed.")
196 loopCount1 = MAX_LOOP_COUNT
197 } else {
198 loopCount1 = Int(Double(loopCount)/secPerLoop)
199 if (loopCount1 == 0) {
200 loopCount1 = 1
201 }
202 }
203 print("Tuning: \(loopCount) ops, \(secPerLoop*1e9/Double(loopCount)) ns/op => \(loopCount1) reps")
204 }
205
runItersnull206 func runIters(phase: String, count: Int, time: Int) throws {
207 totalOps = 0
208 totalSec = 0.0
209 for _ in 1...count {
210 var ops: Int = 0
211 var elapsed: Double = 0.0
212 while (elapsed < Double(time)) {
213 elapsed += try clock.measure {
214 for _ in 0..<loopCount1 {
215 $method_call
216 }
217 }.toDouble
218 ops += loopCount1
219 }
220 totalOps += ops
221 totalSec += elapsed
222 let nsOps = elapsed*1e9/Double(ops)
223 print("\(phase) \(iter):\(ops) ops, \(nsOps) ns/op")
224 iter += 1
225 }
226 }
227
228
229 if (FI > 0) {
230 print("Fast starting $bench_name @ ${fixture}...");
231 var elapsed: Double = try clock.measure {
232 for _ in 0...FI {
233 $method_call
234 }
235 }.toDouble
236 if (elapsed <= 0) {
237 elapsed = 1 // 0 is invalid result
238 }
239 print("Benchmark result: $bench_name \(1.0*elapsed/Double(FI))")
240 } else {
241 try tune()
242 if (WI > 0) {
243 iter = 1
244 for _ in 0..<WI {
245 try runIters(phase: "Warmup", count: 1, time: WT)
246 }
247 }
248 iter = 1
249 try runIters(phase: "Iter", count: MI, time: IT)
250 print("Benchmark result: $bench_name \(totalSec*1e9/Double(totalOps))")
251 }
252 // Teardown
253 Consumer.consumeObj(bench)
254