You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

128 lines
3.2KB

  1. #pragma once
  2. #include <functional>
  3. #include "TimeStatsCollector.h"
  4. template <typename T>
  5. class TestBuffers;
  6. /**
  7. * Used to estimate the amount of time a function takes to execute.
  8. * Will run the function over and over in a tight loop. Return value of function
  9. * is save to testBuffers. Otherwise the compiler might optimize the whole thing away.
  10. * Usually ends by printing out the data.
  11. */
  12. template <typename T>
  13. class MeasureTime
  14. {
  15. public:
  16. /**
  17. * Executes function "func" and measures how long it takes.
  18. * Will call func in a tight look lasting minTime seconds.
  19. * When done, prints out statistics.
  20. */
  21. static void run(const char * name, std::function<T()> func, float minTime)
  22. {
  23. int64_t iterations;
  24. bool done = false;
  25. //keep increasing the number of iterations until we last at least minTime seconds
  26. for (iterations = 100; !done; iterations *= 2) {
  27. double elapsed = measureTimeSub(func, iterations);
  28. if (elapsed >= minTime) {
  29. double itersPerSec = iterations / elapsed;
  30. double full = 44100;
  31. double percent = full * 100 / itersPerSec;
  32. printf("\nmeasure %s over time %f\n", name, minTime);
  33. printf("did %lld iterations in %f seconds\n", iterations, elapsed);
  34. printf("that's %f per sec\n", itersPerSec);
  35. printf("percent CPU usage: %f\n", percent);
  36. printf("best case instances: %f\n", 100 / percent);
  37. printf("quota used per 1 percent : %f\n", percent * 100);
  38. fflush(stdout);
  39. done = true;
  40. }
  41. }
  42. }
  43. /**
  44. * Run test iterators time, return total seconds.
  45. */
  46. static double measureTimeSub(std::function<T()> func, int64_t iterations)
  47. {
  48. const double t0 = SqTime::seconds();
  49. for (int64_t i = 0; i < iterations; ++i) {
  50. const T x = func();
  51. TestBuffers<T>::put(x);
  52. }
  53. const double t1 = SqTime::seconds();
  54. const double elapsed = t1 - t0;
  55. return elapsed;
  56. }
  57. };
  58. /**
  59. * Simple producer / consumer for test data.
  60. * Serves up a precalculated list of random numbers.
  61. */
  62. template <typename T>
  63. class TestBuffers
  64. {
  65. public:
  66. static const size_t size = 60000;
  67. static void put(T x)
  68. {
  69. destData[destIndex++] = x;
  70. if (destIndex >= size) {
  71. destIndex = 0;
  72. }
  73. }
  74. static T get()
  75. {
  76. T ret = sourceData[sourceIndex++];
  77. if (sourceIndex >= size) {
  78. sourceIndex = 0;
  79. }
  80. return ret;
  81. }
  82. //
  83. TestBuffers()
  84. {
  85. for (int i = 0; i < size; ++i) {
  86. sourceData[i] = (float) rand() / (float) RAND_MAX;
  87. }
  88. }
  89. private:
  90. static size_t sourceIndex;
  91. static size_t destIndex;
  92. static T sourceData[size];
  93. static T destData[size];
  94. };
  95. template <typename T>
  96. T TestBuffers<T>::sourceData[size];
  97. template <typename T>
  98. T TestBuffers<T>::destData[size];
  99. template <typename T>
  100. size_t TestBuffers<T>::sourceIndex = 0;
  101. template <typename T>
  102. size_t TestBuffers<T>::destIndex = 512;
  103. /**
  104. * Simple timer implementation for running inside Visual Studio
  105. */