bench.h 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. #pragma once
  2. #include <util/system/compiler.h>
  3. #include <util/system/types.h>
  4. #include <utility>
  5. namespace NBench {
  6. namespace NCpu {
  7. struct TParams {
  8. inline size_t Iterations() const noexcept {
  9. return Iterations_;
  10. }
  11. const size_t Iterations_;
  12. };
  13. using TUserFunc = void(TParams&);
  14. struct TRegistar {
  15. TRegistar(const char* name, TUserFunc func);
  16. char Buf[128];
  17. };
  18. }
  19. /**
  20. * Functions that states "I can read and write everywhere in memory".
  21. *
  22. * Use it to prevent optimizer from reordering or discarding memory writes prior to it's call,
  23. * and force memory reads after it's call.
  24. */
  25. void Clobber();
  26. /**
  27. * Forces whatever `p` points to be in memory and not in register.
  28. *
  29. * @param Pointer to data.
  30. */
  31. template <typename T>
  32. void Escape(T* p);
  33. #if defined(__GNUC__)
  34. Y_FORCE_INLINE void Clobber() {
  35. asm volatile(""
  36. :
  37. :
  38. : "memory");
  39. }
  40. #elif defined(_MSC_VER)
  41. Y_FORCE_INLINE void Clobber() {
  42. _ReadWriteBarrier();
  43. }
  44. #else
  45. Y_FORCE_INLINE void Clobber() {
  46. }
  47. #endif
  48. #if defined(__GNUC__)
  49. template <typename T>
  50. Y_FORCE_INLINE void Escape(T* p) {
  51. asm volatile(""
  52. :
  53. : "g"(p)
  54. : "memory");
  55. }
  56. #else
  57. template <typename T>
  58. Y_FORCE_INLINE void Escape(T*) {
  59. }
  60. #endif
  61. /**
  62. * Use this function to prevent unused variables elimination.
  63. *
  64. * @param Unused variable (e.g. return value of benchmarked function).
  65. */
  66. template <typename T>
  67. Y_FORCE_INLINE void DoNotOptimize(T&& datum) {
  68. ::DoNotOptimizeAway(std::forward<T>(datum));
  69. }
  70. int Main(int argc, char** argv);
  71. }
  72. #define Y_CPU_BENCHMARK(name, cnt) \
  73. namespace N_bench_##name { \
  74. static void Run(::NBench::NCpu::TParams&); \
  75. const ::NBench::NCpu::TRegistar benchmark(#name, &Run); \
  76. } \
  77. static void N_bench_##name::Run(::NBench::NCpu::TParams& cnt)