blob: 05a5f8a2d547db01d721cf0ee042bcd649fad310 [file] [log] [blame]
mtkleinf0599002015-07-13 06:18:39 -07001/*
2 * Copyright 2015 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
tfarinaf168b862014-06-19 12:32:29 -07008#include "Benchmark.h"
reed@google.come05cc8e2011-10-10 14:19:40 +00009#include "SkColorPriv.h"
benjaminwagner6c71e0a2016-04-07 08:49:31 -070010#include "SkFixed.h"
halcanary4dbbd042016-06-07 17:21:10 -070011#include "SkMathPriv.h"
reed@google.comddc518b2011-08-29 17:49:23 +000012#include "SkMatrix.h"
tfarinaf168b862014-06-19 12:32:29 -070013#include "SkPaint.h"
reed@google.comddc518b2011-08-29 17:49:23 +000014#include "SkRandom.h"
15#include "SkString.h"
16
reed@google.com7f192412012-05-30 12:26:52 +000017static float sk_fsel(float pred, float result_ge, float result_lt) {
18 return pred >= 0 ? result_ge : result_lt;
19}
20
21static float fast_floor(float x) {
reed@google.comf3a8d8e2012-05-30 14:08:57 +000022// float big = sk_fsel(x, 0x1.0p+23, -0x1.0p+23);
23 float big = sk_fsel(x, (float)(1 << 23), -(float)(1 << 23));
reed@google.com7f192412012-05-30 12:26:52 +000024 return (x + big) - big;
25}
26
tfarinaf168b862014-06-19 12:32:29 -070027class MathBench : public Benchmark {
reed@google.comddc518b2011-08-29 17:49:23 +000028 enum {
29 kBuffer = 100,
reed@google.comddc518b2011-08-29 17:49:23 +000030 };
31 SkString fName;
32 float fSrc[kBuffer], fDst[kBuffer];
33public:
mtklein@google.com410e6e82013-09-13 19:52:27 +000034 MathBench(const char name[]) {
reed@google.comddc518b2011-08-29 17:49:23 +000035 fName.printf("math_%s", name);
36
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +000037 SkRandom rand;
reed@google.comddc518b2011-08-29 17:49:23 +000038 for (int i = 0; i < kBuffer; ++i) {
39 fSrc[i] = rand.nextSScalar1();
40 }
commit-bot@chromium.org644629c2013-11-21 06:21:58 +000041 }
tomhudson@google.com9dc27132012-09-13 15:50:24 +000042
mtklein36352bf2015-03-25 18:17:31 -070043 bool isSuitableFor(Backend backend) override {
commit-bot@chromium.org644629c2013-11-21 06:21:58 +000044 return backend == kNonRendering_Backend;
reed@google.comddc518b2011-08-29 17:49:23 +000045 }
46
rmistry@google.comfbfcd562012-08-23 18:09:54 +000047 virtual void performTest(float* SK_RESTRICT dst,
48 const float* SK_RESTRICT src,
robertphillips@google.com6853e802012-04-16 15:50:18 +000049 int count) = 0;
reed@google.comddc518b2011-08-29 17:49:23 +000050
51protected:
52 virtual int mulLoopCount() const { return 1; }
53
mtkleinf0599002015-07-13 06:18:39 -070054 const char* onGetName() override {
reed@google.comddc518b2011-08-29 17:49:23 +000055 return fName.c_str();
56 }
57
mtkleina1ebeb22015-10-01 09:43:39 -070058 void onDraw(int loops, SkCanvas*) override {
commit-bot@chromium.org33614712013-12-03 18:17:16 +000059 int n = loops * this->mulLoopCount();
reed@google.comddc518b2011-08-29 17:49:23 +000060 for (int i = 0; i < n; i++) {
61 this->performTest(fDst, fSrc, kBuffer);
62 }
63 }
64
65private:
tfarinaf168b862014-06-19 12:32:29 -070066 typedef Benchmark INHERITED;
reed@google.comddc518b2011-08-29 17:49:23 +000067};
68
reed@google.come05cc8e2011-10-10 14:19:40 +000069class MathBenchU32 : public MathBench {
70public:
mtklein@google.com410e6e82013-09-13 19:52:27 +000071 MathBenchU32(const char name[]) : INHERITED(name) {}
skia.committer@gmail.com81521132013-04-30 07:01:03 +000072
reed@google.come05cc8e2011-10-10 14:19:40 +000073protected:
rmistry@google.comfbfcd562012-08-23 18:09:54 +000074 virtual void performITest(uint32_t* SK_RESTRICT dst,
75 const uint32_t* SK_RESTRICT src,
robertphillips@google.com6853e802012-04-16 15:50:18 +000076 int count) = 0;
skia.committer@gmail.com81521132013-04-30 07:01:03 +000077
mtkleinf0599002015-07-13 06:18:39 -070078 void performTest(float* SK_RESTRICT dst, const float* SK_RESTRICT src, int count) override {
reed@google.come05cc8e2011-10-10 14:19:40 +000079 uint32_t* d = SkTCast<uint32_t*>(dst);
80 const uint32_t* s = SkTCast<const uint32_t*>(src);
81 this->performITest(d, s, count);
82 }
83private:
84 typedef MathBench INHERITED;
85};
86
87///////////////////////////////////////////////////////////////////////////////
reed@google.comddc518b2011-08-29 17:49:23 +000088
89class NoOpMathBench : public MathBench {
90public:
mtklein@google.com410e6e82013-09-13 19:52:27 +000091 NoOpMathBench() : INHERITED("noOp") {}
reed@google.comddc518b2011-08-29 17:49:23 +000092protected:
mtkleinf0599002015-07-13 06:18:39 -070093 void performTest(float* SK_RESTRICT dst, const float* SK_RESTRICT src, int count) override {
reed@google.comddc518b2011-08-29 17:49:23 +000094 for (int i = 0; i < count; ++i) {
95 dst[i] = src[i] + 1;
96 }
97 }
98private:
99 typedef MathBench INHERITED;
100};
101
commit-bot@chromium.org11e5b972013-11-08 20:14:16 +0000102class SkRSqrtMathBench : public MathBench {
103public:
104 SkRSqrtMathBench() : INHERITED("sk_float_rsqrt") {}
105protected:
mtkleinf0599002015-07-13 06:18:39 -0700106 void performTest(float* SK_RESTRICT dst, const float* SK_RESTRICT src, int count) override {
commit-bot@chromium.org11e5b972013-11-08 20:14:16 +0000107 for (int i = 0; i < count; ++i) {
108 dst[i] = sk_float_rsqrt(src[i]);
109 }
110 }
111private:
112 typedef MathBench INHERITED;
113};
114
115
robertphillips@google.com36bb2702013-08-12 12:02:28 +0000116class SlowISqrtMathBench : public MathBench {
reed@google.comddc518b2011-08-29 17:49:23 +0000117public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000118 SlowISqrtMathBench() : INHERITED("slowIsqrt") {}
commit-bot@chromium.orgb3ecdc42013-08-12 08:37:51 +0000119protected:
mtkleinf0599002015-07-13 06:18:39 -0700120 void performTest(float* SK_RESTRICT dst, const float* SK_RESTRICT src, int count) override {
robertphillips@google.com36bb2702013-08-12 12:02:28 +0000121 for (int i = 0; i < count; ++i) {
122 dst[i] = 1.0f / sk_float_sqrt(src[i]);
commit-bot@chromium.orgb3ecdc42013-08-12 08:37:51 +0000123 }
commit-bot@chromium.orgb3ecdc42013-08-12 08:37:51 +0000124 }
reed@google.comddc518b2011-08-29 17:49:23 +0000125private:
robertphillips@google.com36bb2702013-08-12 12:02:28 +0000126 typedef MathBench INHERITED;
127};
128
129static inline float SkFastInvSqrt(float x) {
130 float xhalf = 0.5f*x;
mtklein1f6a1bd2015-12-08 10:53:01 -0800131 uint32_t i = *SkTCast<uint32_t*>(&x);
robertphillips@google.com36bb2702013-08-12 12:02:28 +0000132 i = 0x5f3759df - (i>>1);
133 x = *SkTCast<float*>(&i);
134 x = x*(1.5f-xhalf*x*x);
135// x = x*(1.5f-xhalf*x*x); // this line takes err from 10^-3 to 10^-6
136 return x;
137}
138
139class FastISqrtMathBench : public MathBench {
140public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000141 FastISqrtMathBench() : INHERITED("fastIsqrt") {}
robertphillips@google.com36bb2702013-08-12 12:02:28 +0000142protected:
mtkleinf0599002015-07-13 06:18:39 -0700143 void performTest(float* SK_RESTRICT dst, const float* SK_RESTRICT src, int count) override {
robertphillips@google.com36bb2702013-08-12 12:02:28 +0000144 for (int i = 0; i < count; ++i) {
145 dst[i] = SkFastInvSqrt(src[i]);
146 }
147 }
148private:
149 typedef MathBench INHERITED;
reed@google.comddc518b2011-08-29 17:49:23 +0000150};
151
reed@google.come05cc8e2011-10-10 14:19:40 +0000152static inline uint32_t QMul64(uint32_t value, U8CPU alpha) {
153 SkASSERT((uint8_t)alpha == alpha);
154 const uint32_t mask = 0xFF00FF;
155
156 uint64_t tmp = value;
157 tmp = (tmp & mask) | ((tmp & ~mask) << 24);
158 tmp *= alpha;
caryclark@google.com19069a22012-06-06 12:11:45 +0000159 return (uint32_t) (((tmp >> 8) & mask) | ((tmp >> 32) & ~mask));
reed@google.come05cc8e2011-10-10 14:19:40 +0000160}
161
162class QMul64Bench : public MathBenchU32 {
163public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000164 QMul64Bench() : INHERITED("qmul64") {}
reed@google.come05cc8e2011-10-10 14:19:40 +0000165protected:
mtkleinf0599002015-07-13 06:18:39 -0700166 void performITest(uint32_t* SK_RESTRICT dst,
167 const uint32_t* SK_RESTRICT src,
168 int count) override {
reed@google.come05cc8e2011-10-10 14:19:40 +0000169 for (int i = 0; i < count; ++i) {
170 dst[i] = QMul64(src[i], (uint8_t)i);
171 }
172 }
173private:
174 typedef MathBenchU32 INHERITED;
175};
176
177class QMul32Bench : public MathBenchU32 {
178public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000179 QMul32Bench() : INHERITED("qmul32") {}
reed@google.come05cc8e2011-10-10 14:19:40 +0000180protected:
mtkleinf0599002015-07-13 06:18:39 -0700181 void performITest(uint32_t* SK_RESTRICT dst,
182 const uint32_t* SK_RESTRICT src,
183 int count) override {
reed@google.come05cc8e2011-10-10 14:19:40 +0000184 for (int i = 0; i < count; ++i) {
185 dst[i] = SkAlphaMulQ(src[i], (uint8_t)i);
186 }
187 }
188private:
189 typedef MathBenchU32 INHERITED;
190};
191
reed@google.comddc518b2011-08-29 17:49:23 +0000192///////////////////////////////////////////////////////////////////////////////
193
reed@google.com0be5eb72011-12-05 21:53:22 +0000194static bool isFinite_int(float x) {
195 uint32_t bits = SkFloat2Bits(x); // need unsigned for our shifts
196 int exponent = bits << 1 >> 24;
197 return exponent != 0xFF;
198}
199
200static bool isFinite_float(float x) {
robertphillips@google.com6853e802012-04-16 15:50:18 +0000201 return SkToBool(sk_float_isfinite(x));
reed@google.com0be5eb72011-12-05 21:53:22 +0000202}
203
204static bool isFinite_mulzero(float x) {
205 float y = x * 0;
206 return y == y;
207}
208
209static bool isfinite_and_int(const float data[4]) {
210 return isFinite_int(data[0]) && isFinite_int(data[1]) && isFinite_int(data[2]) && isFinite_int(data[3]);
211}
212
213static bool isfinite_and_float(const float data[4]) {
214 return isFinite_float(data[0]) && isFinite_float(data[1]) && isFinite_float(data[2]) && isFinite_float(data[3]);
215}
216
217static bool isfinite_and_mulzero(const float data[4]) {
218 return isFinite_mulzero(data[0]) && isFinite_mulzero(data[1]) && isFinite_mulzero(data[2]) && isFinite_mulzero(data[3]);
219}
220
221#define mulzeroadd(data) (data[0]*0 + data[1]*0 + data[2]*0 + data[3]*0)
222
223static bool isfinite_plus_int(const float data[4]) {
224 return isFinite_int(mulzeroadd(data));
225}
226
227static bool isfinite_plus_float(const float data[4]) {
reed@google.com5ae777d2011-12-06 20:18:05 +0000228 return !sk_float_isnan(mulzeroadd(data));
reed@google.com0be5eb72011-12-05 21:53:22 +0000229}
230
231static bool isfinite_plus_mulzero(const float data[4]) {
232 float x = mulzeroadd(data);
233 return x == x;
234}
235
236typedef bool (*IsFiniteProc)(const float[]);
237
238#define MAKEREC(name) { name, #name }
239
240static const struct {
241 IsFiniteProc fProc;
242 const char* fName;
243} gRec[] = {
244 MAKEREC(isfinite_and_int),
245 MAKEREC(isfinite_and_float),
246 MAKEREC(isfinite_and_mulzero),
247 MAKEREC(isfinite_plus_int),
248 MAKEREC(isfinite_plus_float),
249 MAKEREC(isfinite_plus_mulzero),
250};
251
252#undef MAKEREC
253
reed@google.com16078632011-12-06 18:56:37 +0000254static bool isFinite(const SkRect& r) {
255 // x * 0 will be NaN iff x is infinity or NaN.
256 // a + b will be NaN iff either a or b is NaN.
257 float value = r.fLeft * 0 + r.fTop * 0 + r.fRight * 0 + r.fBottom * 0;
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000258
reed@google.com16078632011-12-06 18:56:37 +0000259 // value is either NaN or it is finite (zero).
260 // value==value will be true iff value is not NaN
261 return value == value;
262}
263
tfarinaf168b862014-06-19 12:32:29 -0700264class IsFiniteBench : public Benchmark {
reed@google.com0be5eb72011-12-05 21:53:22 +0000265 enum {
mtklein@google.comc2897432013-09-10 19:23:38 +0000266 N = 1000,
reed@google.com0be5eb72011-12-05 21:53:22 +0000267 };
268 float fData[N];
269public:
270
mtklein@google.com410e6e82013-09-13 19:52:27 +0000271 IsFiniteBench(int index) {
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000272 SkRandom rand;
reed@google.com0be5eb72011-12-05 21:53:22 +0000273
274 for (int i = 0; i < N; ++i) {
275 fData[i] = rand.nextSScalar1();
276 }
reed@google.com16078632011-12-06 18:56:37 +0000277
278 if (index < 0) {
halcanary96fcdcc2015-08-27 07:41:13 -0700279 fProc = nullptr;
reed@google.com16078632011-12-06 18:56:37 +0000280 fName = "isfinite_rect";
281 } else {
282 fProc = gRec[index].fProc;
283 fName = gRec[index].fName;
284 }
commit-bot@chromium.org644629c2013-11-21 06:21:58 +0000285 }
286
mtklein36352bf2015-03-25 18:17:31 -0700287 bool isSuitableFor(Backend backend) override {
commit-bot@chromium.org644629c2013-11-21 06:21:58 +0000288 return backend == kNonRendering_Backend;
reed@google.com0be5eb72011-12-05 21:53:22 +0000289 }
290
291protected:
mtkleina1ebeb22015-10-01 09:43:39 -0700292 void onDraw(int loops, SkCanvas*) override {
reed@google.com0be5eb72011-12-05 21:53:22 +0000293 IsFiniteProc proc = fProc;
294 const float* data = fData;
reed@google.com16078632011-12-06 18:56:37 +0000295 // do this so the compiler won't throw away the function call
296 int counter = 0;
reed@google.com0be5eb72011-12-05 21:53:22 +0000297
reed@google.com16078632011-12-06 18:56:37 +0000298 if (proc) {
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000299 for (int j = 0; j < loops; ++j) {
reed@google.com16078632011-12-06 18:56:37 +0000300 for (int i = 0; i < N - 4; ++i) {
301 counter += proc(&data[i]);
302 }
reed@google.com0be5eb72011-12-05 21:53:22 +0000303 }
reed@google.com16078632011-12-06 18:56:37 +0000304 } else {
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000305 for (int j = 0; j < loops; ++j) {
reed@google.com16078632011-12-06 18:56:37 +0000306 for (int i = 0; i < N - 4; ++i) {
307 const SkRect* r = reinterpret_cast<const SkRect*>(&data[i]);
caryclark@google.com19069a22012-06-06 12:11:45 +0000308 if (false) { // avoid bit rot, suppress warning
309 isFinite(*r);
310 }
reed@google.com16078632011-12-06 18:56:37 +0000311 counter += r->isFinite();
312 }
313 }
314 }
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000315
reed@google.com16078632011-12-06 18:56:37 +0000316 SkPaint paint;
317 if (paint.getAlpha() == 0) {
318 SkDebugf("%d\n", counter);
reed@google.com0be5eb72011-12-05 21:53:22 +0000319 }
320 }
321
mtkleinf0599002015-07-13 06:18:39 -0700322 const char* onGetName() override {
reed@google.com0be5eb72011-12-05 21:53:22 +0000323 return fName;
324 }
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000325
reed@google.com0be5eb72011-12-05 21:53:22 +0000326private:
327 IsFiniteProc fProc;
328 const char* fName;
329
tfarinaf168b862014-06-19 12:32:29 -0700330 typedef Benchmark INHERITED;
reed@google.com0be5eb72011-12-05 21:53:22 +0000331};
332
tfarinaf168b862014-06-19 12:32:29 -0700333class FloorBench : public Benchmark {
reed@google.com7f192412012-05-30 12:26:52 +0000334 enum {
mtklein@google.comc2897432013-09-10 19:23:38 +0000335 ARRAY = 1000,
reed@google.com7f192412012-05-30 12:26:52 +0000336 };
337 float fData[ARRAY];
338 bool fFast;
339public:
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000340
mtklein@google.com410e6e82013-09-13 19:52:27 +0000341 FloorBench(bool fast) : fFast(fast) {
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000342 SkRandom rand;
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000343
reed@google.com7f192412012-05-30 12:26:52 +0000344 for (int i = 0; i < ARRAY; ++i) {
345 fData[i] = rand.nextSScalar1();
346 }
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000347
reed@google.com7f192412012-05-30 12:26:52 +0000348 if (fast) {
349 fName = "floor_fast";
350 } else {
351 fName = "floor_std";
352 }
commit-bot@chromium.org644629c2013-11-21 06:21:58 +0000353 }
354
mtklein36352bf2015-03-25 18:17:31 -0700355 bool isSuitableFor(Backend backend) override {
commit-bot@chromium.org644629c2013-11-21 06:21:58 +0000356 return backend == kNonRendering_Backend;
reed@google.com7f192412012-05-30 12:26:52 +0000357 }
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000358
reed@google.com7f192412012-05-30 12:26:52 +0000359 virtual void process(float) {}
360
361protected:
mtkleina1ebeb22015-10-01 09:43:39 -0700362 void onDraw(int loops, SkCanvas*) override {
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000363 SkRandom rand;
reed@google.com7f192412012-05-30 12:26:52 +0000364 float accum = 0;
365 const float* data = fData;
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000366
reed@google.com7f192412012-05-30 12:26:52 +0000367 if (fFast) {
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000368 for (int j = 0; j < loops; ++j) {
reed@google.com7f192412012-05-30 12:26:52 +0000369 for (int i = 0; i < ARRAY; ++i) {
370 accum += fast_floor(data[i]);
371 }
372 this->process(accum);
373 }
374 } else {
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000375 for (int j = 0; j < loops; ++j) {
reed@google.com7f192412012-05-30 12:26:52 +0000376 for (int i = 0; i < ARRAY; ++i) {
377 accum += sk_float_floor(data[i]);
378 }
379 this->process(accum);
380 }
381 }
382 }
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000383
mtkleinf0599002015-07-13 06:18:39 -0700384 const char* onGetName() override {
reed@google.com7f192412012-05-30 12:26:52 +0000385 return fName;
386 }
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000387
reed@google.com7f192412012-05-30 12:26:52 +0000388private:
389 const char* fName;
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000390
tfarinaf168b862014-06-19 12:32:29 -0700391 typedef Benchmark INHERITED;
reed@google.com7f192412012-05-30 12:26:52 +0000392};
393
tfarinaf168b862014-06-19 12:32:29 -0700394class CLZBench : public Benchmark {
reed@google.com0d7aac92013-04-29 13:55:11 +0000395 enum {
mtklein@google.comc2897432013-09-10 19:23:38 +0000396 ARRAY = 1000,
reed@google.com0d7aac92013-04-29 13:55:11 +0000397 };
398 uint32_t fData[ARRAY];
399 bool fUsePortable;
400
skia.committer@gmail.com81521132013-04-30 07:01:03 +0000401public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000402 CLZBench(bool usePortable) : fUsePortable(usePortable) {
reed@google.com0d7aac92013-04-29 13:55:11 +0000403
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000404 SkRandom rand;
reed@google.com0d7aac92013-04-29 13:55:11 +0000405 for (int i = 0; i < ARRAY; ++i) {
406 fData[i] = rand.nextU();
407 }
skia.committer@gmail.com81521132013-04-30 07:01:03 +0000408
reed@google.com0d7aac92013-04-29 13:55:11 +0000409 if (fUsePortable) {
410 fName = "clz_portable";
411 } else {
412 fName = "clz_intrinsic";
413 }
commit-bot@chromium.org644629c2013-11-21 06:21:58 +0000414 }
415
mtklein36352bf2015-03-25 18:17:31 -0700416 bool isSuitableFor(Backend backend) override {
commit-bot@chromium.org644629c2013-11-21 06:21:58 +0000417 return backend == kNonRendering_Backend;
reed@google.com0d7aac92013-04-29 13:55:11 +0000418 }
skia.committer@gmail.com81521132013-04-30 07:01:03 +0000419
reed@google.com0d7aac92013-04-29 13:55:11 +0000420 // just so the compiler doesn't remove our loops
421 virtual void process(int) {}
skia.committer@gmail.com81521132013-04-30 07:01:03 +0000422
reed@google.com0d7aac92013-04-29 13:55:11 +0000423protected:
mtkleina1ebeb22015-10-01 09:43:39 -0700424 void onDraw(int loops, SkCanvas*) override {
reed@google.com0d7aac92013-04-29 13:55:11 +0000425 int accum = 0;
skia.committer@gmail.com81521132013-04-30 07:01:03 +0000426
reed@google.com0d7aac92013-04-29 13:55:11 +0000427 if (fUsePortable) {
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000428 for (int j = 0; j < loops; ++j) {
reed@google.com0d7aac92013-04-29 13:55:11 +0000429 for (int i = 0; i < ARRAY; ++i) {
430 accum += SkCLZ_portable(fData[i]);
431 }
432 this->process(accum);
433 }
434 } else {
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000435 for (int j = 0; j < loops; ++j) {
reed@google.com0d7aac92013-04-29 13:55:11 +0000436 for (int i = 0; i < ARRAY; ++i) {
437 accum += SkCLZ(fData[i]);
438 }
439 this->process(accum);
440 }
441 }
442 }
skia.committer@gmail.com81521132013-04-30 07:01:03 +0000443
mtkleinf0599002015-07-13 06:18:39 -0700444 const char* onGetName() override {
reed@google.com0d7aac92013-04-29 13:55:11 +0000445 return fName;
446 }
skia.committer@gmail.com81521132013-04-30 07:01:03 +0000447
reed@google.com0d7aac92013-04-29 13:55:11 +0000448private:
449 const char* fName;
skia.committer@gmail.com81521132013-04-30 07:01:03 +0000450
tfarinaf168b862014-06-19 12:32:29 -0700451 typedef Benchmark INHERITED;
reed@google.com0d7aac92013-04-29 13:55:11 +0000452};
453
reed@google.com0be5eb72011-12-05 21:53:22 +0000454///////////////////////////////////////////////////////////////////////////////
455
tfarinaf168b862014-06-19 12:32:29 -0700456class NormalizeBench : public Benchmark {
reed@google.com0889f682013-05-03 12:56:39 +0000457 enum {
mtklein@google.comc2897432013-09-10 19:23:38 +0000458 ARRAY =1000,
reed@google.com0889f682013-05-03 12:56:39 +0000459 };
460 SkVector fVec[ARRAY];
skia.committer@gmail.comecc9d282013-05-04 07:01:15 +0000461
reed@google.com0889f682013-05-03 12:56:39 +0000462public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000463 NormalizeBench() {
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000464 SkRandom rand;
reed@google.com0889f682013-05-03 12:56:39 +0000465 for (int i = 0; i < ARRAY; ++i) {
466 fVec[i].set(rand.nextSScalar1(), rand.nextSScalar1());
467 }
skia.committer@gmail.comecc9d282013-05-04 07:01:15 +0000468
reed@google.com0889f682013-05-03 12:56:39 +0000469 fName = "point_normalize";
commit-bot@chromium.org644629c2013-11-21 06:21:58 +0000470 }
471
mtklein36352bf2015-03-25 18:17:31 -0700472 bool isSuitableFor(Backend backend) override {
commit-bot@chromium.org644629c2013-11-21 06:21:58 +0000473 return backend == kNonRendering_Backend;
reed@google.com0889f682013-05-03 12:56:39 +0000474 }
skia.committer@gmail.comecc9d282013-05-04 07:01:15 +0000475
reed@google.com0889f682013-05-03 12:56:39 +0000476 // just so the compiler doesn't remove our loops
477 virtual void process(int) {}
skia.committer@gmail.comecc9d282013-05-04 07:01:15 +0000478
reed@google.com0889f682013-05-03 12:56:39 +0000479protected:
mtkleina1ebeb22015-10-01 09:43:39 -0700480 void onDraw(int loops, SkCanvas*) override {
reed@google.com0889f682013-05-03 12:56:39 +0000481 int accum = 0;
skia.committer@gmail.comecc9d282013-05-04 07:01:15 +0000482
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000483 for (int j = 0; j < loops; ++j) {
reed@google.com0889f682013-05-03 12:56:39 +0000484 for (int i = 0; i < ARRAY; ++i) {
485 accum += fVec[i].normalize();
486 }
487 this->process(accum);
488 }
489 }
skia.committer@gmail.comecc9d282013-05-04 07:01:15 +0000490
mtkleinf0599002015-07-13 06:18:39 -0700491 const char* onGetName() override {
reed@google.com0889f682013-05-03 12:56:39 +0000492 return fName;
493 }
skia.committer@gmail.comecc9d282013-05-04 07:01:15 +0000494
reed@google.com0889f682013-05-03 12:56:39 +0000495private:
496 const char* fName;
skia.committer@gmail.comecc9d282013-05-04 07:01:15 +0000497
tfarinaf168b862014-06-19 12:32:29 -0700498 typedef Benchmark INHERITED;
reed@google.com0889f682013-05-03 12:56:39 +0000499};
500
501///////////////////////////////////////////////////////////////////////////////
502
tfarinaf168b862014-06-19 12:32:29 -0700503class FixedMathBench : public Benchmark {
djsollen@google.com25a11e42013-07-18 19:11:30 +0000504 enum {
mtklein@google.comc2897432013-09-10 19:23:38 +0000505 N = 1000,
djsollen@google.com25a11e42013-07-18 19:11:30 +0000506 };
507 float fData[N];
508 SkFixed fResult[N];
509public:
510
mtklein@google.com410e6e82013-09-13 19:52:27 +0000511 FixedMathBench() {
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000512 SkRandom rand;
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000513 for (int i = 0; i < N; ++i) {
514 fData[i] = rand.nextSScalar1();
djsollen@google.com25a11e42013-07-18 19:11:30 +0000515 }
516
commit-bot@chromium.org644629c2013-11-21 06:21:58 +0000517 }
518
mtklein36352bf2015-03-25 18:17:31 -0700519 bool isSuitableFor(Backend backend) override {
commit-bot@chromium.org644629c2013-11-21 06:21:58 +0000520 return backend == kNonRendering_Backend;
djsollen@google.com25a11e42013-07-18 19:11:30 +0000521 }
522
523protected:
mtkleina1ebeb22015-10-01 09:43:39 -0700524 void onDraw(int loops, SkCanvas*) override {
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000525 for (int j = 0; j < loops; ++j) {
djsollen@google.com25a11e42013-07-18 19:11:30 +0000526 for (int i = 0; i < N - 4; ++i) {
527 fResult[i] = SkFloatToFixed(fData[i]);
528 }
529 }
530
531 SkPaint paint;
532 if (paint.getAlpha() == 0) {
533 SkDebugf("%d\n", fResult[0]);
534 }
535 }
536
mtkleinf0599002015-07-13 06:18:39 -0700537 const char* onGetName() override {
djsollen@google.com25a11e42013-07-18 19:11:30 +0000538 return "float_to_fixed";
539 }
540
541private:
tfarinaf168b862014-06-19 12:32:29 -0700542 typedef Benchmark INHERITED;
djsollen@google.com25a11e42013-07-18 19:11:30 +0000543};
544
545///////////////////////////////////////////////////////////////////////////////
546
commit-bot@chromium.org2c86fbb2013-09-26 19:22:54 +0000547template <typename T>
tfarinaf168b862014-06-19 12:32:29 -0700548class DivModBench : public Benchmark {
mtklein@google.com9cb51772013-09-27 13:39:14 +0000549 SkString fName;
commit-bot@chromium.org2c86fbb2013-09-26 19:22:54 +0000550public:
mtklein@google.com9cb51772013-09-27 13:39:14 +0000551 explicit DivModBench(const char* name) {
552 fName.printf("divmod_%s", name);
commit-bot@chromium.org644629c2013-11-21 06:21:58 +0000553 }
554
mtklein36352bf2015-03-25 18:17:31 -0700555 bool isSuitableFor(Backend backend) override {
commit-bot@chromium.org644629c2013-11-21 06:21:58 +0000556 return backend == kNonRendering_Backend;
commit-bot@chromium.org2c86fbb2013-09-26 19:22:54 +0000557 }
558
559protected:
mtkleinf0599002015-07-13 06:18:39 -0700560 const char* onGetName() override {
mtklein@google.com9cb51772013-09-27 13:39:14 +0000561 return fName.c_str();
commit-bot@chromium.org2c86fbb2013-09-26 19:22:54 +0000562 }
563
mtkleina1ebeb22015-10-01 09:43:39 -0700564 void onDraw(int loops, SkCanvas*) override {
commit-bot@chromium.org2c86fbb2013-09-26 19:22:54 +0000565 volatile T a = 0, b = 0;
566 T div = 0, mod = 0;
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000567 for (int i = 0; i < loops; i++) {
commit-bot@chromium.org2c86fbb2013-09-26 19:22:54 +0000568 if ((T)i == 0) continue; // Small T will wrap around.
569 SkTDivMod((T)(i+1), (T)i, &div, &mod);
570 a ^= div;
571 b ^= mod;
572 }
573 }
574};
575DEF_BENCH(return new DivModBench<uint8_t>("uint8_t"))
576DEF_BENCH(return new DivModBench<uint16_t>("uint16_t"))
577DEF_BENCH(return new DivModBench<uint32_t>("uint32_t"))
578DEF_BENCH(return new DivModBench<uint64_t>("uint64_t"))
579
580DEF_BENCH(return new DivModBench<int8_t>("int8_t"))
581DEF_BENCH(return new DivModBench<int16_t>("int16_t"))
582DEF_BENCH(return new DivModBench<int32_t>("int32_t"))
583DEF_BENCH(return new DivModBench<int64_t>("int64_t"))
584
585///////////////////////////////////////////////////////////////////////////////
586
mtklein@google.com410e6e82013-09-13 19:52:27 +0000587DEF_BENCH( return new NoOpMathBench(); )
commit-bot@chromium.org11e5b972013-11-08 20:14:16 +0000588DEF_BENCH( return new SkRSqrtMathBench(); )
mtklein@google.com410e6e82013-09-13 19:52:27 +0000589DEF_BENCH( return new SlowISqrtMathBench(); )
590DEF_BENCH( return new FastISqrtMathBench(); )
591DEF_BENCH( return new QMul64Bench(); )
592DEF_BENCH( return new QMul32Bench(); )
reed@google.comddc518b2011-08-29 17:49:23 +0000593
mtklein@google.com410e6e82013-09-13 19:52:27 +0000594DEF_BENCH( return new IsFiniteBench(-1); )
595DEF_BENCH( return new IsFiniteBench(0); )
596DEF_BENCH( return new IsFiniteBench(1); )
597DEF_BENCH( return new IsFiniteBench(2); )
598DEF_BENCH( return new IsFiniteBench(3); )
599DEF_BENCH( return new IsFiniteBench(4); )
600DEF_BENCH( return new IsFiniteBench(5); )
reed@google.com0be5eb72011-12-05 21:53:22 +0000601
mtklein@google.com410e6e82013-09-13 19:52:27 +0000602DEF_BENCH( return new FloorBench(false); )
603DEF_BENCH( return new FloorBench(true); )
reed@google.com7f192412012-05-30 12:26:52 +0000604
mtklein@google.com410e6e82013-09-13 19:52:27 +0000605DEF_BENCH( return new CLZBench(false); )
606DEF_BENCH( return new CLZBench(true); )
reed@google.com0889f682013-05-03 12:56:39 +0000607
mtklein@google.com410e6e82013-09-13 19:52:27 +0000608DEF_BENCH( return new NormalizeBench(); )
djsollen@google.com25a11e42013-07-18 19:11:30 +0000609
mtklein@google.com410e6e82013-09-13 19:52:27 +0000610DEF_BENCH( return new FixedMathBench(); )
mtklein785a5b92016-05-27 10:47:31 -0700611
612
613struct FloatToIntBench : public Benchmark {
614 enum { N = 1000000 };
615 float fFloats[N];
616 int fInts [N];
617
618 const char* onGetName() override { return "float_to_int"; }
619 bool isSuitableFor(Backend backend) override { return backend == kNonRendering_Backend; }
620
621 void onDelayedSetup() override {
622 const auto f32 = 4294967296.0f;
623 for (int i = 0; i < N; ++i) {
624 fFloats[i] = -f32 + i*(2*f32/N);
625 }
626 }
627
628 void onDraw(int loops, SkCanvas*) override {
629 while (loops --> 0) {
630 for (int i = 0; i < N; i++) {
631 fInts[i] = SkFloatToIntFloor(fFloats[i]);
632 }
633 }
634 }
635};
636DEF_BENCH( return new FloatToIntBench; )