Home | History | Annotate | Download | only in bench
      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 
      8 #include "SkTypes.h"
      9 
     10 #include "Benchmark.h"
     11 #include "GrMemoryPool.h"
     12 #include "SkRandom.h"
     13 #include "SkTDArray.h"
     14 #include "SkTemplates.h"
     15 
     16 #include <new>
     17 
     18 // change this to 0 to compare GrMemoryPool to default new / delete
     19 #define OVERRIDE_NEW    1
     20 
     21 struct A {
     22     int gStuff[10];
     23 #if OVERRIDE_NEW
     24     void* operator new (size_t size) { return gBenchPool.allocate(size); }
     25     void operator delete (void* mem) { if (mem) { return gBenchPool.release(mem); } }
     26 #endif
     27     static GrMemoryPool gBenchPool;
     28 };
     29 GrMemoryPool A::gBenchPool(10 * (1 << 10), 10 * (1 << 10));
     30 
     31 /**
     32  * This benchmark creates and deletes objects in stack order
     33  */
     34 class GrMemoryPoolBenchStack : public Benchmark {
     35 public:
     36     bool isSuitableFor(Backend backend) override {
     37         return backend == kNonRendering_Backend;
     38     }
     39 
     40 protected:
     41     const char* onGetName() override {
     42         return "grmemorypool_stack";
     43     }
     44 
     45     void onDraw(int loops, SkCanvas*) override {
     46         SkRandom r;
     47         enum {
     48             kMaxObjects = 4 * (1 << 10),
     49         };
     50         A* objects[kMaxObjects];
     51 
     52         // We delete if a random number [-1, 1] is < the thresh. Otherwise,
     53         // we allocate. We start allocate-biased and ping-pong to delete-biased
     54         SkScalar delThresh = -SK_ScalarHalf;
     55         const int kSwitchThreshPeriod = loops / (2 * kMaxObjects);
     56         int s = 0;
     57 
     58         int count = 0;
     59         for (int i = 0; i < loops; i++, ++s) {
     60             if (kSwitchThreshPeriod == s) {
     61                 delThresh = -delThresh;
     62                 s = 0;
     63             }
     64             SkScalar del = r.nextSScalar1();
     65             if (count &&
     66                 (kMaxObjects == count || del < delThresh)) {
     67                 delete objects[count-1];
     68                 --count;
     69             } else {
     70                 objects[count] = new A;
     71                 ++count;
     72             }
     73         }
     74         for (int i = 0; i < count; ++i) {
     75             delete objects[i];
     76         }
     77     }
     78 
     79 private:
     80     typedef Benchmark INHERITED;
     81 };
     82 
     83 struct B {
     84     int gStuff[10];
     85 #if OVERRIDE_NEW
     86     void* operator new (size_t size) { return gBenchPool.allocate(size); }
     87     void operator delete (void* mem) { if (mem) { return gBenchPool.release(mem); } }
     88 #endif
     89     static GrMemoryPool gBenchPool;
     90 };
     91 GrMemoryPool B::gBenchPool(10 * (1 << 10), 10 * (1 << 10));
     92 
     93 /**
     94  * This benchmark creates objects and deletes them in random order
     95  */
     96 class GrMemoryPoolBenchRandom : public Benchmark {
     97 public:
     98     bool isSuitableFor(Backend backend) override {
     99         return backend == kNonRendering_Backend;
    100     }
    101 
    102 protected:
    103     const char* onGetName() override {
    104         return "grmemorypool_random";
    105     }
    106 
    107     void onDraw(int loops, SkCanvas*) override {
    108         SkRandom r;
    109         enum {
    110             kMaxObjects = 4 * (1 << 10),
    111         };
    112         std::unique_ptr<B> objects[kMaxObjects];
    113 
    114         for (int i = 0; i < loops; i++) {
    115             uint32_t idx = r.nextRangeU(0, kMaxObjects-1);
    116             if (nullptr == objects[idx].get()) {
    117                 objects[idx].reset(new B);
    118             } else {
    119                 objects[idx].reset();
    120             }
    121         }
    122     }
    123 
    124 private:
    125     typedef Benchmark INHERITED;
    126 };
    127 
    128 struct C {
    129     int gStuff[10];
    130 #if OVERRIDE_NEW
    131     void* operator new (size_t size) { return gBenchPool.allocate(size); }
    132     void operator delete (void* mem) { if (mem) { return gBenchPool.release(mem); } }
    133 #endif
    134     static GrMemoryPool gBenchPool;
    135 };
    136 GrMemoryPool C::gBenchPool(10 * (1 << 10), 10 * (1 << 10));
    137 
    138 /**
    139  * This benchmark creates objects and deletes them in queue order
    140  */
    141 class GrMemoryPoolBenchQueue : public Benchmark {
    142     enum {
    143         M = 4 * (1 << 10),
    144     };
    145 public:
    146     bool isSuitableFor(Backend backend) override {
    147         return backend == kNonRendering_Backend;
    148     }
    149 
    150 protected:
    151     const char* onGetName() override {
    152         return "grmemorypool_queue";
    153     }
    154 
    155     void onDraw(int loops, SkCanvas*) override {
    156         SkRandom r;
    157         C* objects[M];
    158         for (int i = 0; i < loops; i++) {
    159             uint32_t count = r.nextRangeU(0, M-1);
    160             for (uint32_t i = 0; i < count; i++) {
    161                 objects[i] = new C;
    162             }
    163             for (uint32_t i = 0; i < count; i++) {
    164                 delete objects[i];
    165             }
    166         }
    167     }
    168 
    169 private:
    170     typedef Benchmark INHERITED;
    171 };
    172 
    173 ///////////////////////////////////////////////////////////////////////////////
    174 
    175 DEF_BENCH( return new GrMemoryPoolBenchStack(); )
    176 DEF_BENCH( return new GrMemoryPoolBenchRandom(); )
    177 DEF_BENCH( return new GrMemoryPoolBenchQueue(); )
    178