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 "SkString.h"
     12 
     13 class ScalarBench : public SkBenchmark {
     14     SkString    fName;
     15     enum { N = 100000 };
     16 public:
     17     ScalarBench(void* param, const char name[]) : INHERITED(param) {
     18         fName.printf("scalar_%s", name);
     19     }
     20 
     21     virtual void performTest() = 0;
     22 
     23 protected:
     24     virtual int mulLoopCount() const { return 1; }
     25 
     26     virtual const char* onGetName() {
     27         return fName.c_str();
     28     }
     29 
     30     virtual void onDraw(SkCanvas* canvas) {
     31         int n = SkBENCHLOOP(N * this->mulLoopCount());
     32         for (int i = 0; i < n; i++) {
     33             this->performTest();
     34         }
     35     }
     36 
     37 private:
     38     typedef SkBenchmark INHERITED;
     39 };
     40 
     41 // we want to stop the compiler from eliminating code that it thinks is a no-op
     42 // so we have a non-static global we increment, hoping that will convince the
     43 // compiler to execute everything
     44 int gScalarBench_NonStaticGlobal;
     45 
     46 #define always_do(pred)                     \
     47     do {                                    \
     48         if (pred) {                         \
     49             ++gScalarBench_NonStaticGlobal; \
     50         }                                   \
     51     } while (0)
     52 
     53 // having unknown values in our arrays can throw off the timing a lot, perhaps
     54 // handling NaN values is a lot slower. Anyway, this guy is just meant to put
     55 // reasonable values in our arrays.
     56 template <typename T> void init9(T array[9]) {
     57     SkRandom rand;
     58     for (int i = 0; i < 9; i++) {
     59         array[i] = rand.nextSScalar1();
     60     }
     61 }
     62 
     63 class FloatComparisonBench : public ScalarBench {
     64 public:
     65     FloatComparisonBench(void* param) : INHERITED(param, "compare_float") {
     66         init9(fArray);
     67     }
     68 protected:
     69     virtual int mulLoopCount() const { return 4; }
     70     virtual void performTest() {
     71         always_do(fArray[6] != 0.0f || fArray[7] != 0.0f || fArray[8] != 1.0f);
     72         always_do(fArray[2] != 0.0f || fArray[5] != 0.0f);
     73     }
     74 private:
     75     float fArray[9];
     76     typedef ScalarBench INHERITED;
     77 };
     78 
     79 class ForcedIntComparisonBench : public ScalarBench {
     80 public:
     81     ForcedIntComparisonBench(void* param)
     82         : INHERITED(param, "compare_forced_int") {
     83         init9(fArray);
     84     }
     85 protected:
     86     virtual int mulLoopCount() const { return 4; }
     87     virtual void performTest() {
     88         always_do(SkScalarAs2sCompliment(fArray[6]) |
     89                   SkScalarAs2sCompliment(fArray[7]) |
     90                   (SkScalarAs2sCompliment(fArray[8]) - kPersp1Int));
     91         always_do(SkScalarAs2sCompliment(fArray[2]) |
     92                   SkScalarAs2sCompliment(fArray[5]));
     93     }
     94 private:
     95     static const int32_t kPersp1Int = 0x3f800000;
     96     SkScalar fArray[9];
     97     typedef ScalarBench INHERITED;
     98 };
     99 
    100 static SkBenchmark* S0(void* p) { return new FloatComparisonBench(p); }
    101 static SkBenchmark* S1(void* p) { return new ForcedIntComparisonBench(p); }
    102 
    103 static BenchRegistry gReg0(S0);
    104 static BenchRegistry gReg1(S1);
    105