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