ScalarBench.cpp 4.6 KB

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