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