blob: 2d547b7883028ae7309741acd48034059e44a6e5 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
2/*
3 * Copyright 2011 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
tomhudson@google.comf910b362011-06-06 15:16:31 +00008#include "SkBenchmark.h"
tomhudson@google.com25583a32011-06-06 17:55:11 +00009#include "SkFloatBits.h"
tomhudson@google.comf910b362011-06-06 15:16:31 +000010#include "SkRandom.h"
reed@google.com63c57612012-05-15 14:14:04 +000011#include "SkRect.h"
tomhudson@google.comf910b362011-06-06 15:16:31 +000012#include "SkString.h"
13
14class ScalarBench : public SkBenchmark {
15 SkString fName;
16 enum { N = 100000 };
17public:
18 ScalarBench(void* param, const char name[]) : INHERITED(param) {
19 fName.printf("scalar_%s", name);
20 }
21
22 virtual void performTest() = 0;
23
24protected:
25 virtual int mulLoopCount() const { return 1; }
26
reed@google.com357818c2012-06-13 12:30:35 +000027 virtual const char* onGetName() SK_OVERRIDE {
tomhudson@google.comf910b362011-06-06 15:16:31 +000028 return fName.c_str();
29 }
30
31 virtual void onDraw(SkCanvas* canvas) {
tomhudson@google.comca529d32011-10-28 15:34:49 +000032 int n = SkBENCHLOOP(N * this->mulLoopCount());
tomhudson@google.comf910b362011-06-06 15:16:31 +000033 for (int i = 0; i < n; i++) {
34 this->performTest();
35 }
36 }
37
38private:
39 typedef SkBenchmark INHERITED;
40};
41
42// we want to stop the compiler from eliminating code that it thinks is a no-op
43// so we have a non-static global we increment, hoping that will convince the
44// compiler to execute everything
45int gScalarBench_NonStaticGlobal;
46
47#define always_do(pred) \
48 do { \
49 if (pred) { \
50 ++gScalarBench_NonStaticGlobal; \
51 } \
52 } while (0)
53
54// having unknown values in our arrays can throw off the timing a lot, perhaps
55// handling NaN values is a lot slower. Anyway, this guy is just meant to put
56// reasonable values in our arrays.
57template <typename T> void init9(T array[9]) {
58 SkRandom rand;
59 for (int i = 0; i < 9; i++) {
60 array[i] = rand.nextSScalar1();
61 }
62}
63
64class FloatComparisonBench : public ScalarBench {
65public:
66 FloatComparisonBench(void* param) : INHERITED(param, "compare_float") {
67 init9(fArray);
68 }
69protected:
70 virtual int mulLoopCount() const { return 4; }
71 virtual void performTest() {
72 always_do(fArray[6] != 0.0f || fArray[7] != 0.0f || fArray[8] != 1.0f);
73 always_do(fArray[2] != 0.0f || fArray[5] != 0.0f);
74 }
75private:
76 float fArray[9];
77 typedef ScalarBench INHERITED;
78};
79
80class ForcedIntComparisonBench : public ScalarBench {
81public:
82 ForcedIntComparisonBench(void* param)
reed@google.com357818c2012-06-13 12:30:35 +000083 : INHERITED(param, "compare_forced_int") {
tomhudson@google.comf910b362011-06-06 15:16:31 +000084 init9(fArray);
85 }
86protected:
87 virtual int mulLoopCount() const { return 4; }
88 virtual void performTest() {
89 always_do(SkScalarAs2sCompliment(fArray[6]) |
90 SkScalarAs2sCompliment(fArray[7]) |
91 (SkScalarAs2sCompliment(fArray[8]) - kPersp1Int));
92 always_do(SkScalarAs2sCompliment(fArray[2]) |
93 SkScalarAs2sCompliment(fArray[5]));
94 }
95private:
96 static const int32_t kPersp1Int = 0x3f800000;
tomhudson@google.com25583a32011-06-06 17:55:11 +000097 SkScalar fArray[9];
tomhudson@google.comf910b362011-06-06 15:16:31 +000098 typedef ScalarBench INHERITED;
99};
100
reed@google.com357818c2012-06-13 12:30:35 +0000101class IsFiniteScalarBench : public ScalarBench {
102public:
103 IsFiniteScalarBench(void* param) : INHERITED(param, "isfinite") {
104 SkRandom rand;
105 for (size_t i = 0; i < ARRAY_N; ++i) {
106 fArray[i] = rand.nextSScalar1();
107 }
108 }
109protected:
110 virtual int mulLoopCount() const { return 1; }
111 virtual void performTest() SK_OVERRIDE {
112 int sum = 0;
113 for (size_t i = 0; i < ARRAY_N; ++i) {
114 // We pass -fArray[i], so the compiler can't cheat and treat the
115 // value as an int (even though we tell it that it is a float)
116 sum += SkScalarIsFinite(-fArray[i]);
117 }
118 // we do this so the compiler won't optimize our loop away...
119 this->doSomething(fArray, sum);
120 }
121
122 virtual void doSomething(SkScalar array[], int sum) {}
123private:
124 enum {
125 ARRAY_N = 64
126 };
127 SkScalar fArray[ARRAY_N];
128
129 typedef ScalarBench INHERITED;
130};
131
reed@google.com63c57612012-05-15 14:14:04 +0000132///////////////////////////////////////////////////////////////////////////////
133
134class RectBoundsBench : public SkBenchmark {
135 enum {
136 PTS = 100,
137 N = SkBENCHLOOP(10000)
138 };
139 SkPoint fPts[PTS];
140
141public:
142 RectBoundsBench(void* param) : INHERITED(param) {
143 SkRandom rand;
144 for (int i = 0; i < PTS; ++i) {
145 fPts[i].fX = rand.nextSScalar1();
146 fPts[i].fY = rand.nextSScalar1();
147 }
148 }
149
150protected:
151 virtual const char* onGetName() SK_OVERRIDE {
152 return "rect_bounds";
153 }
154
155 virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
156 SkRect r;
157 for (int i = 0; i < N; ++i) {
158 r.set(fPts, PTS);
159 }
160 }
161
162private:
163 typedef SkBenchmark INHERITED;
164};
165
166///////////////////////////////////////////////////////////////////////////////
167
tomhudson@google.comf910b362011-06-06 15:16:31 +0000168static SkBenchmark* S0(void* p) { return new FloatComparisonBench(p); }
169static SkBenchmark* S1(void* p) { return new ForcedIntComparisonBench(p); }
reed@google.com63c57612012-05-15 14:14:04 +0000170static SkBenchmark* S2(void* p) { return new RectBoundsBench(p); }
reed@google.com357818c2012-06-13 12:30:35 +0000171static SkBenchmark* S3(void* p) { return new IsFiniteScalarBench(p); }
tomhudson@google.comf910b362011-06-06 15:16:31 +0000172
173static BenchRegistry gReg0(S0);
174static BenchRegistry gReg1(S1);
reed@google.com63c57612012-05-15 14:14:04 +0000175static BenchRegistry gReg2(S2);
reed@google.com357818c2012-06-13 12:30:35 +0000176static BenchRegistry gReg3(S3);