1 /*
2  * Copyright 2012 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 #include <memory>
8 #include "Benchmark.h"
9 #include "SkRefCnt.h"
10 #include "SkThread.h"
11 #include "SkWeakRefCnt.h"
12 
13 enum {
14     M = 2
15 };
16 
17 class AtomicInc32 : public Benchmark {
18 public:
AtomicInc32()19     AtomicInc32() : fX(0) {}
20 
isSuitableFor(Backend backend)21     bool isSuitableFor(Backend backend) override {
22         return backend == kNonRendering_Backend;
23     }
24 
25 protected:
onGetName()26     virtual const char* onGetName() {
27         return "atomic_inc_32";
28     }
29 
onDraw(const int loops,SkCanvas *)30     virtual void onDraw(const int loops, SkCanvas*) {
31         for (int i = 0; i < loops; ++i) {
32             sk_atomic_inc(&fX);
33         }
34     }
35 
36 private:
37     int32_t fX;
38     typedef Benchmark INHERITED;
39 };
40 
41 class AtomicInc64 : public Benchmark {
42 public:
AtomicInc64()43     AtomicInc64() : fX(0) {}
44 
isSuitableFor(Backend backend)45     bool isSuitableFor(Backend backend) override {
46         return backend == kNonRendering_Backend;
47     }
48 
49 protected:
onGetName()50     virtual const char* onGetName() {
51         return "atomic_inc_64";
52     }
53 
onDraw(const int loops,SkCanvas *)54     virtual void onDraw(const int loops, SkCanvas*) {
55         for (int i = 0; i < loops; ++i) {
56             sk_atomic_inc(&fX);
57         }
58     }
59 
60 private:
61     int64_t fX;
62     typedef Benchmark INHERITED;
63 };
64 
65 class RefCntBench_Stack : public Benchmark {
66 public:
isSuitableFor(Backend backend)67     bool isSuitableFor(Backend backend) override {
68         return backend == kNonRendering_Backend;
69     }
70 
71 protected:
onGetName()72     virtual const char* onGetName() {
73         return "ref_cnt_stack";
74     }
75 
onDraw(const int loops,SkCanvas *)76     virtual void onDraw(const int loops, SkCanvas*) {
77         for (int i = 0; i < loops; ++i) {
78             SkRefCnt ref;
79             for (int j = 0; j < M; ++j) {
80                 ref.ref();
81                 ref.unref();
82             }
83         }
84     }
85 
86 private:
87     typedef Benchmark INHERITED;
88 };
89 
90 class PlacedRefCnt : public SkRefCnt {
91 public:
92     SK_DECLARE_INST_COUNT(PlacedRefCnt)
93 
PlacedRefCnt()94     PlacedRefCnt() : SkRefCnt() { }
operator delete(void *)95     void operator delete(void*) { }
96 
97 private:
98     typedef SkRefCnt INHERITED;
99 };
100 
101 class RefCntBench_Heap : public Benchmark {
102 public:
isSuitableFor(Backend backend)103     bool isSuitableFor(Backend backend) override {
104         return backend == kNonRendering_Backend;
105     }
106 
107 protected:
onGetName()108     virtual const char* onGetName() {
109         return "ref_cnt_heap";
110     }
111 
onDraw(const int loops,SkCanvas *)112     virtual void onDraw(const int loops, SkCanvas*) {
113         char memory[sizeof(PlacedRefCnt)];
114         for (int i = 0; i < loops; ++i) {
115             PlacedRefCnt* ref = new (memory) PlacedRefCnt();
116             for (int j = 0; j < M; ++j) {
117                 ref->ref();
118                 ref->unref();
119             }
120             ref->unref();
121         }
122     }
123 
124 private:
125     typedef Benchmark INHERITED;
126 };
127 
128 class RefCntBench_New : public Benchmark {
129 public:
isSuitableFor(Backend backend)130     bool isSuitableFor(Backend backend) override {
131         return backend == kNonRendering_Backend;
132     }
133 
134 protected:
onGetName()135     virtual const char* onGetName() {
136         return "ref_cnt_new";
137     }
138 
onDraw(const int loops,SkCanvas *)139     virtual void onDraw(const int loops, SkCanvas*) {
140         for (int i = 0; i < loops; ++i) {
141             SkRefCnt* ref = new SkRefCnt();
142             for (int j = 0; j < M; ++j) {
143                 ref->ref();
144                 ref->unref();
145             }
146             ref->unref();
147         }
148     }
149 
150 private:
151     typedef Benchmark INHERITED;
152 };
153 
154 ///////////////////////////////////////////////////////////////////////////////
155 
156 class WeakRefCntBench_Stack : public Benchmark {
157 public:
isSuitableFor(Backend backend)158     bool isSuitableFor(Backend backend) override {
159         return backend == kNonRendering_Backend;
160     }
161 
162 protected:
onGetName()163     virtual const char* onGetName() {
164         return "ref_cnt_stack_weak";
165     }
166 
onDraw(const int loops,SkCanvas *)167     virtual void onDraw(const int loops, SkCanvas*) {
168         for (int i = 0; i < loops; ++i) {
169             SkWeakRefCnt ref;
170             for (int j = 0; j < M; ++j) {
171                 ref.ref();
172                 ref.unref();
173             }
174         }
175     }
176 
177 private:
178     typedef Benchmark INHERITED;
179 };
180 
181 class PlacedWeakRefCnt : public SkWeakRefCnt {
182 public:
PlacedWeakRefCnt()183     PlacedWeakRefCnt() : SkWeakRefCnt() { }
operator delete(void *)184     void operator delete(void*) { }
185 };
186 
187 class WeakRefCntBench_Heap : public Benchmark {
188 public:
isSuitableFor(Backend backend)189     bool isSuitableFor(Backend backend) override {
190         return backend == kNonRendering_Backend;
191     }
192 
193 protected:
onGetName()194     const char* onGetName() override {
195         return "ref_cnt_heap_weak";
196     }
197 
onDraw(const int loops,SkCanvas *)198     void onDraw(const int loops, SkCanvas*) override {
199         char memory[sizeof(PlacedWeakRefCnt)];
200         for (int i = 0; i < loops; ++i) {
201             PlacedWeakRefCnt* ref = new (memory) PlacedWeakRefCnt();
202             for (int j = 0; j < M; ++j) {
203                 ref->ref();
204                 ref->unref();
205             }
206             ref->unref();
207         }
208     }
209 
210 private:
211     typedef Benchmark INHERITED;
212 };
213 
214 class WeakRefCntBench_New : public Benchmark {
215 public:
isSuitableFor(Backend backend)216     bool isSuitableFor(Backend backend) override {
217         return backend == kNonRendering_Backend;
218     }
219 
220 protected:
onGetName()221     const char* onGetName() override {
222         return "ref_cnt_new_weak";
223     }
224 
onDraw(const int loops,SkCanvas *)225     void onDraw(const int loops, SkCanvas*) override {
226         for (int i = 0; i < loops; ++i) {
227             SkWeakRefCnt* ref = new SkWeakRefCnt();
228             for (int j = 0; j < M; ++j) {
229                 ref->ref();
230                 ref->unref();
231             }
232             ref->unref();
233         }
234     }
235 
236 private:
237     typedef Benchmark INHERITED;
238 };
239 
240 ///////////////////////////////////////////////////////////////////////////////
241 
242 DEF_BENCH( return new AtomicInc32(); )
243 DEF_BENCH( return new AtomicInc64(); )
244 
245 DEF_BENCH( return new RefCntBench_Stack(); )
246 DEF_BENCH( return new RefCntBench_Heap(); )
247 DEF_BENCH( return new RefCntBench_New(); )
248 
249 DEF_BENCH( return new WeakRefCntBench_Stack(); )
250 DEF_BENCH( return new WeakRefCntBench_Heap(); )
251 DEF_BENCH( return new WeakRefCntBench_New(); )
252