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