GrMemoryPoolBench.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. /*
  2. * Copyright 2012 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 "include/core/SkTypes.h"
  8. #include "bench/Benchmark.h"
  9. #include "include/private/SkTDArray.h"
  10. #include "include/private/SkTemplates.h"
  11. #include "include/utils/SkRandom.h"
  12. #include "src/gpu/GrMemoryPool.h"
  13. #include <new>
  14. // change this to 0 to compare GrMemoryPool to default new / delete
  15. #define OVERRIDE_NEW 1
  16. struct A {
  17. int gStuff[10];
  18. #if OVERRIDE_NEW
  19. void* operator new (size_t size) { return gBenchPool.allocate(size); }
  20. void operator delete (void* mem) { if (mem) { return gBenchPool.release(mem); } }
  21. #endif
  22. static GrMemoryPool gBenchPool;
  23. };
  24. GrMemoryPool A::gBenchPool(10 * (1 << 10), 10 * (1 << 10));
  25. /**
  26. * This benchmark creates and deletes objects in stack order
  27. */
  28. class GrMemoryPoolBenchStack : public Benchmark {
  29. public:
  30. bool isSuitableFor(Backend backend) override {
  31. return backend == kNonRendering_Backend;
  32. }
  33. protected:
  34. const char* onGetName() override {
  35. return "grmemorypool_stack";
  36. }
  37. void onDraw(int loops, SkCanvas*) override {
  38. SkRandom r;
  39. enum {
  40. kMaxObjects = 4 * (1 << 10),
  41. };
  42. A* objects[kMaxObjects];
  43. // We delete if a random number [-1, 1] is < the thresh. Otherwise,
  44. // we allocate. We start allocate-biased and ping-pong to delete-biased
  45. SkScalar delThresh = -SK_ScalarHalf;
  46. const int kSwitchThreshPeriod = loops / (2 * kMaxObjects);
  47. int s = 0;
  48. int count = 0;
  49. for (int i = 0; i < loops; i++, ++s) {
  50. if (kSwitchThreshPeriod == s) {
  51. delThresh = -delThresh;
  52. s = 0;
  53. }
  54. SkScalar del = r.nextSScalar1();
  55. if (count &&
  56. (kMaxObjects == count || del < delThresh)) {
  57. delete objects[count-1];
  58. --count;
  59. } else {
  60. objects[count] = new A;
  61. ++count;
  62. }
  63. }
  64. for (int i = 0; i < count; ++i) {
  65. delete objects[i];
  66. }
  67. }
  68. private:
  69. typedef Benchmark INHERITED;
  70. };
  71. struct B {
  72. int gStuff[10];
  73. #if OVERRIDE_NEW
  74. void* operator new (size_t size) { return gBenchPool.allocate(size); }
  75. void operator delete (void* mem) { if (mem) { return gBenchPool.release(mem); } }
  76. #endif
  77. static GrMemoryPool gBenchPool;
  78. };
  79. GrMemoryPool B::gBenchPool(10 * (1 << 10), 10 * (1 << 10));
  80. /**
  81. * This benchmark creates objects and deletes them in random order
  82. */
  83. class GrMemoryPoolBenchRandom : public Benchmark {
  84. public:
  85. bool isSuitableFor(Backend backend) override {
  86. return backend == kNonRendering_Backend;
  87. }
  88. protected:
  89. const char* onGetName() override {
  90. return "grmemorypool_random";
  91. }
  92. void onDraw(int loops, SkCanvas*) override {
  93. SkRandom r;
  94. enum {
  95. kMaxObjects = 4 * (1 << 10),
  96. };
  97. std::unique_ptr<B> objects[kMaxObjects];
  98. for (int i = 0; i < loops; i++) {
  99. uint32_t idx = r.nextRangeU(0, kMaxObjects-1);
  100. if (nullptr == objects[idx].get()) {
  101. objects[idx].reset(new B);
  102. } else {
  103. objects[idx].reset();
  104. }
  105. }
  106. }
  107. private:
  108. typedef Benchmark INHERITED;
  109. };
  110. struct C {
  111. int gStuff[10];
  112. #if OVERRIDE_NEW
  113. void* operator new (size_t size) { return gBenchPool.allocate(size); }
  114. void operator delete (void* mem) { if (mem) { return gBenchPool.release(mem); } }
  115. #endif
  116. static GrMemoryPool gBenchPool;
  117. };
  118. GrMemoryPool C::gBenchPool(10 * (1 << 10), 10 * (1 << 10));
  119. /**
  120. * This benchmark creates objects and deletes them in queue order
  121. */
  122. class GrMemoryPoolBenchQueue : public Benchmark {
  123. enum {
  124. M = 4 * (1 << 10),
  125. };
  126. public:
  127. bool isSuitableFor(Backend backend) override {
  128. return backend == kNonRendering_Backend;
  129. }
  130. protected:
  131. const char* onGetName() override {
  132. return "grmemorypool_queue";
  133. }
  134. void onDraw(int loops, SkCanvas*) override {
  135. SkRandom r;
  136. C* objects[M];
  137. for (int i = 0; i < loops; i++) {
  138. uint32_t count = r.nextRangeU(0, M-1);
  139. for (uint32_t i = 0; i < count; i++) {
  140. objects[i] = new C;
  141. }
  142. for (uint32_t i = 0; i < count; i++) {
  143. delete objects[i];
  144. }
  145. }
  146. }
  147. private:
  148. typedef Benchmark INHERITED;
  149. };
  150. ///////////////////////////////////////////////////////////////////////////////
  151. DEF_BENCH( return new GrMemoryPoolBenchStack(); )
  152. DEF_BENCH( return new GrMemoryPoolBenchRandom(); )
  153. DEF_BENCH( return new GrMemoryPoolBenchQueue(); )