15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright 2012 Google Inc.
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Use of this source code is governed by a BSD-style license that can be
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * found in the LICENSE file.
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "Benchmark.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "SkCanvas.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "SkChunkAlloc.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "SkPaint.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "SkRandom.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "SkString.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ChunkAllocBench : public Benchmark {
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkString    fName;
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_t      fMinSize;
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)public:
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ChunkAllocBench(size_t minSize)  {
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        fMinSize = minSize;
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        fName.printf("chunkalloc_" SK_SIZE_T_SPECIFIER, minSize);
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual bool isSuitableFor(Backend backend) SK_OVERRIDE {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return backend == kNonRendering_Backend;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)protected:
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual const char* onGetName() SK_OVERRIDE {
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return fName.c_str();
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual void onDraw(const int loops, SkCanvas*) SK_OVERRIDE {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        size_t inc = fMinSize >> 4;
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        SkASSERT(inc > 0);
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        size_t total = fMinSize * 64;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        SkChunkAlloc alloc(fMinSize);
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        for (int i = 0; i < loops; ++i) {
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            size_t size = 0;
42            int calls = 0;
43            while (size < total) {
44                alloc.allocThrow(inc);
45                size += inc;
46                calls += 1;
47            }
48            alloc.reset();
49        }
50    }
51
52private:
53    typedef Benchmark INHERITED;
54};
55
56DEF_BENCH( return new ChunkAllocBench(64); )
57DEF_BENCH( return new ChunkAllocBench(8*1024); )
58
59static int* calloc(size_t num) {
60    return (int*)sk_calloc_throw(num*sizeof(int));
61}
62
63static int* malloc_bzero(size_t num) {
64    const size_t bytes = num*sizeof(int);
65    int* ints = (int*)sk_malloc_throw(bytes);
66    sk_bzero(ints, bytes);
67    return ints;
68}
69
70class ZerosBench : public Benchmark {
71    size_t   fNum;
72    bool     fRead;
73    bool     fWrite;
74    bool     fUseCalloc;
75    SkString fName;
76public:
77    ZerosBench(size_t num, bool read, bool write, bool useCalloc)
78        : fNum(num)
79        , fRead(read)
80        , fWrite(write)
81        , fUseCalloc(useCalloc) {
82        fName.printf("memory_%s", useCalloc ? "calloc" : "malloc_bzero");
83        if (read && write) {
84            fName.appendf("_rw");
85        } else if (read) {
86            fName.appendf("_r");
87        } else if (write) {
88            fName.appendf("_w");
89        }
90        fName.appendf("_"SK_SIZE_T_SPECIFIER, num);
91    }
92
93    virtual bool isSuitableFor(Backend backend) SK_OVERRIDE {
94        return backend == kNonRendering_Backend;
95    }
96
97protected:
98    virtual const char* onGetName() SK_OVERRIDE {
99        return fName.c_str();
100    }
101
102    virtual void onDraw(const int loops, SkCanvas*) SK_OVERRIDE {
103        for (int i = 0; i < loops; i++) {
104            int* zeros = fUseCalloc ? calloc(fNum) : malloc_bzero(fNum);
105            if (fRead) {
106                volatile int x = 15;
107                for (size_t j = 0; j < fNum; j++) {
108                    x ^= zeros[j];
109                }
110            }
111            if (fWrite) {
112                for (size_t j = 0; j < fNum; j++) {
113                    zeros[j] = 15;
114                }
115            }
116            sk_free(zeros);
117        }
118    }
119};
120
121//                             zero count  r  w  useCalloc?
122DEF_BENCH(return new ZerosBench(1024*1024, 0, 0, 0))
123DEF_BENCH(return new ZerosBench(1024*1024, 0, 0, 1))
124DEF_BENCH(return new ZerosBench(1024*1024, 0, 1, 0))
125DEF_BENCH(return new ZerosBench(1024*1024, 0, 1, 1))
126DEF_BENCH(return new ZerosBench(1024*1024, 1, 0, 0))
127DEF_BENCH(return new ZerosBench(1024*1024, 1, 0, 1))
128DEF_BENCH(return new ZerosBench(1024*1024, 1, 1, 0))
129DEF_BENCH(return new ZerosBench(1024*1024, 1, 1, 1))
130
131DEF_BENCH(return new ZerosBench(256*1024, 0, 0, 0))
132DEF_BENCH(return new ZerosBench(256*1024, 0, 0, 1))
133DEF_BENCH(return new ZerosBench(256*1024, 0, 1, 0))
134DEF_BENCH(return new ZerosBench(256*1024, 0, 1, 1))
135DEF_BENCH(return new ZerosBench(256*1024, 1, 0, 0))
136DEF_BENCH(return new ZerosBench(256*1024, 1, 0, 1))
137DEF_BENCH(return new ZerosBench(256*1024, 1, 1, 0))
138DEF_BENCH(return new ZerosBench(256*1024, 1, 1, 1))
139
140DEF_BENCH(return new ZerosBench(4*1024, 0, 0, 0))
141DEF_BENCH(return new ZerosBench(4*1024, 0, 0, 1))
142DEF_BENCH(return new ZerosBench(4*1024, 0, 1, 0))
143DEF_BENCH(return new ZerosBench(4*1024, 0, 1, 1))
144DEF_BENCH(return new ZerosBench(4*1024, 1, 0, 0))
145DEF_BENCH(return new ZerosBench(4*1024, 1, 0, 1))
146DEF_BENCH(return new ZerosBench(4*1024, 1, 1, 0))
147DEF_BENCH(return new ZerosBench(4*1024, 1, 1, 1))
148
149DEF_BENCH(return new ZerosBench(300, 0, 0, 0))
150DEF_BENCH(return new ZerosBench(300, 0, 0, 1))
151DEF_BENCH(return new ZerosBench(300, 0, 1, 0))
152DEF_BENCH(return new ZerosBench(300, 0, 1, 1))
153DEF_BENCH(return new ZerosBench(300, 1, 0, 0))
154DEF_BENCH(return new ZerosBench(300, 1, 0, 1))
155DEF_BENCH(return new ZerosBench(300, 1, 1, 0))
156DEF_BENCH(return new ZerosBench(300, 1, 1, 1))
157
158DEF_BENCH(return new ZerosBench(4, 0, 0, 0))
159DEF_BENCH(return new ZerosBench(4, 0, 0, 1))
160DEF_BENCH(return new ZerosBench(4, 0, 1, 0))
161DEF_BENCH(return new ZerosBench(4, 0, 1, 1))
162DEF_BENCH(return new ZerosBench(4, 1, 0, 0))
163DEF_BENCH(return new ZerosBench(4, 1, 0, 1))
164DEF_BENCH(return new ZerosBench(4, 1, 1, 0))
165DEF_BENCH(return new ZerosBench(4, 1, 1, 1))
166