Home | History | Annotate | Download | only in bench
      1 
      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  */
      8 #include "SkBenchmark.h"
      9 #include "SkFloatBits.h"
     10 #include "SkRandom.h"
     11 #include "SkRect.h"
     12 #include "SkString.h"
     13 
     14 class ScalarBench : public SkBenchmark {
     15     SkString    fName;
     16     enum { N = 100000 };
     17 public:
     18     ScalarBench(void* param, const char name[]) : INHERITED(param) {
     19         fName.printf("scalar_%s", name);
     20         fIsRendering = false;
     21     }
     22 
     23     virtual void performTest() = 0;
     24 
     25 protected:
     26     virtual int mulLoopCount() const { return 1; }
     27 
     28     virtual const char* onGetName() SK_OVERRIDE {
     29         return fName.c_str();
     30     }
     31 
     32     virtual void onDraw(SkCanvas* canvas) {
     33         int n = SkBENCHLOOP(N * this->mulLoopCount());
     34         for (int i = 0; i < n; i++) {
     35             this->performTest();
     36         }
     37     }
     38 
     39 private:
     40     typedef SkBenchmark INHERITED;
     41 };
     42 
     43 // we want to stop the compiler from eliminating code that it thinks is a no-op
     44 // so we have a non-static global we increment, hoping that will convince the
     45 // compiler to execute everything
     46 int gScalarBench_NonStaticGlobal;
     47 
     48 #define always_do(pred)                     \
     49     do {                                    \
     50         if (pred) {                         \
     51             ++gScalarBench_NonStaticGlobal; \
     52         }                                   \
     53     } while (0)
     54 
     55 // having unknown values in our arrays can throw off the timing a lot, perhaps
     56 // handling NaN values is a lot slower. Anyway, this guy is just meant to put
     57 // reasonable values in our arrays.
     58 template <typename T> void init9(T array[9]) {
     59     SkRandom rand;
     60     for (int i = 0; i < 9; i++) {
     61         array[i] = rand.nextSScalar1();
     62     }
     63 }
     64 
     65 class FloatComparisonBench : public ScalarBench {
     66 public:
     67     FloatComparisonBench(void* param) : INHERITED(param, "compare_float") {
     68         init9(fArray);
     69     }
     70 protected:
     71     virtual int mulLoopCount() const { return 4; }
     72     virtual void performTest() {
     73         always_do(fArray[6] != 0.0f || fArray[7] != 0.0f || fArray[8] != 1.0f);
     74         always_do(fArray[2] != 0.0f || fArray[5] != 0.0f);
     75     }
     76 private:
     77     float fArray[9];
     78     typedef ScalarBench INHERITED;
     79 };
     80 
     81 class ForcedIntComparisonBench : public ScalarBench {
     82 public:
     83     ForcedIntComparisonBench(void* param)
     84     : INHERITED(param, "compare_forced_int") {
     85         init9(fArray);
     86     }
     87 protected:
     88     virtual int mulLoopCount() const { return 4; }
     89     virtual void performTest() {
     90         always_do(SkScalarAs2sCompliment(fArray[6]) |
     91                   SkScalarAs2sCompliment(fArray[7]) |
     92                   (SkScalarAs2sCompliment(fArray[8]) - kPersp1Int));
     93         always_do(SkScalarAs2sCompliment(fArray[2]) |
     94                   SkScalarAs2sCompliment(fArray[5]));
     95     }
     96 private:
     97     static const int32_t kPersp1Int = 0x3f800000;
     98     SkScalar fArray[9];
     99     typedef ScalarBench INHERITED;
    100 };
    101 
    102 class IsFiniteScalarBench : public ScalarBench {
    103 public:
    104     IsFiniteScalarBench(void* param) : INHERITED(param, "isfinite") {
    105         SkRandom rand;
    106         for (size_t i = 0; i < ARRAY_N; ++i) {
    107             fArray[i] = rand.nextSScalar1();
    108         }
    109     }
    110 protected:
    111     virtual int mulLoopCount() const { return 1; }
    112     virtual void performTest() SK_OVERRIDE {
    113         int sum = 0;
    114         for (size_t i = 0; i < ARRAY_N; ++i) {
    115             // We pass -fArray[i], so the compiler can't cheat and treat the
    116             // value as an int (even though we tell it that it is a float)
    117             sum += SkScalarIsFinite(-fArray[i]);
    118         }
    119         // we do this so the compiler won't optimize our loop away...
    120         this->doSomething(fArray, sum);
    121     }
    122 
    123     virtual void doSomething(SkScalar array[], int sum) {}
    124 private:
    125     enum {
    126         ARRAY_N = 64
    127     };
    128     SkScalar fArray[ARRAY_N];
    129 
    130     typedef ScalarBench INHERITED;
    131 };
    132 
    133 ///////////////////////////////////////////////////////////////////////////////
    134 
    135 class RectBoundsBench : public SkBenchmark {
    136     enum {
    137         PTS = 100,
    138         N = SkBENCHLOOP(10000)
    139     };
    140     SkPoint fPts[PTS];
    141 
    142 public:
    143     RectBoundsBench(void* param) : INHERITED(param) {
    144         SkRandom rand;
    145         for (int i = 0; i < PTS; ++i) {
    146             fPts[i].fX = rand.nextSScalar1();
    147             fPts[i].fY = rand.nextSScalar1();
    148         }
    149         fIsRendering = false;
    150     }
    151 
    152 protected:
    153     virtual const char* onGetName() SK_OVERRIDE {
    154         return "rect_bounds";
    155     }
    156 
    157     virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
    158         SkRect r;
    159         for (int i = 0; i < N; ++i) {
    160             r.set(fPts, PTS);
    161         }
    162     }
    163 
    164 private:
    165     typedef SkBenchmark INHERITED;
    166 };
    167 
    168 ///////////////////////////////////////////////////////////////////////////////
    169 
    170 static SkBenchmark* S0(void* p) { return new FloatComparisonBench(p); }
    171 static SkBenchmark* S1(void* p) { return new ForcedIntComparisonBench(p); }
    172 static SkBenchmark* S2(void* p) { return new RectBoundsBench(p); }
    173 static SkBenchmark* S3(void* p) { return new IsFiniteScalarBench(p); }
    174 
    175 static BenchRegistry gReg0(S0);
    176 static BenchRegistry gReg1(S1);
    177 static BenchRegistry gReg2(S2);
    178 static BenchRegistry gReg3(S3);
    179