cputimer.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. #include "cputimer.h"
  2. #include <util/system/defaults.h>
  3. #include <util/system/hp_timer.h>
  4. #include <util/string/printf.h>
  5. #include <util/stream/output.h>
  6. #include <util/generic/singleton.h>
  7. #if defined(_unix_)
  8. #include <unistd.h>
  9. #include <sched.h>
  10. #elif defined(_win_)
  11. #include <util/system/winint.h>
  12. #endif
  13. TTimer::TTimer(const TStringBuf message) {
  14. static const int SMALL_DURATION_CHAR_LENGTH = 9; // strlen("0.123456s")
  15. Message_.Reserve(message.length() + SMALL_DURATION_CHAR_LENGTH + 1); // +"\n"
  16. Message_ << message;
  17. // Do not measure the allocations above.
  18. Start_ = TInstant::Now();
  19. }
  20. TTimer::~TTimer() {
  21. const TDuration duration = TInstant::Now() - Start_;
  22. Message_ << duration << "\n";
  23. Cerr << Message_.Str();
  24. }
  25. static ui64 ManuallySetCyclesPerSecond = 0;
  26. static ui64 GetCyclesPerSecond() {
  27. if (ManuallySetCyclesPerSecond != 0) {
  28. return ManuallySetCyclesPerSecond;
  29. } else {
  30. return NHPTimer::GetCyclesPerSecond();
  31. }
  32. }
  33. void SetCyclesPerSecond(ui64 cycles) {
  34. ManuallySetCyclesPerSecond = cycles;
  35. }
  36. ui64 GetCyclesPerMillisecond() {
  37. return GetCyclesPerSecond() / 1000;
  38. }
  39. TDuration CyclesToDuration(ui64 cycles) {
  40. return TDuration::MicroSeconds(cycles * 1000000 / GetCyclesPerSecond());
  41. }
  42. TDuration CyclesToDurationSafe(ui64 cycles)
  43. {
  44. constexpr ui64 cyclesLimit = std::numeric_limits<ui64>::max() / 1000000;
  45. if (cycles <= cyclesLimit) {
  46. return CyclesToDuration(cycles);
  47. }
  48. return TDuration::MicroSeconds(cycles / GetCyclesPerSecond() * 1000000);
  49. }
  50. ui64 DurationToCycles(TDuration duration) {
  51. return duration.MicroSeconds() * GetCyclesPerSecond() / 1000000;
  52. }
  53. ui64 DurationToCyclesSafe(TDuration duration)
  54. {
  55. if (duration.MicroSeconds() <= std::numeric_limits<ui64>::max() / GetCyclesPerSecond()) {
  56. return DurationToCycles(duration);
  57. }
  58. return duration.MicroSeconds() / 1000000 * GetCyclesPerSecond();
  59. }
  60. TPrecisionTimer::TPrecisionTimer()
  61. : Start(::GetCycleCount())
  62. {
  63. }
  64. ui64 TPrecisionTimer::GetCycleCount() const {
  65. return ::GetCycleCount() - Start;
  66. }
  67. TString FormatCycles(ui64 cycles) {
  68. ui64 milliseconds = cycles / GetCyclesPerMillisecond();
  69. ui32 ms = ui32(milliseconds % 1000);
  70. milliseconds /= 1000;
  71. ui32 secs = ui32(milliseconds % 60);
  72. milliseconds /= 60;
  73. ui32 mins = ui32(milliseconds);
  74. TString result;
  75. sprintf(result, "%" PRIu32 " m %.2" PRIu32 " s %.3" PRIu32 " ms", mins, secs, ms);
  76. return result;
  77. }
  78. TFormattedPrecisionTimer::TFormattedPrecisionTimer(const char* message, IOutputStream* out)
  79. : Message(message)
  80. , Out(out)
  81. {
  82. Start = GetCycleCount();
  83. }
  84. TFormattedPrecisionTimer::~TFormattedPrecisionTimer() {
  85. const ui64 end = GetCycleCount();
  86. const ui64 diff = end - Start;
  87. *Out << Message << ": " << diff << " ticks " << FormatCycles(diff) << Endl;
  88. }
  89. TFuncTimer::TFuncTimer(const char* func)
  90. : Start_(TInstant::Now())
  91. , Func_(func)
  92. {
  93. Cerr << "enter " << Func_ << Endl;
  94. }
  95. TFuncTimer::~TFuncTimer() {
  96. Cerr << "leave " << Func_ << " -> " << (TInstant::Now() - Start_) << Endl;
  97. }
  98. TTimeLogger::TTimeLogger(const TString& message, bool verbose)
  99. : Message(message)
  100. , Verbose(verbose)
  101. , OK(false)
  102. , Begin(time(nullptr))
  103. , BeginCycles(GetCycleCount())
  104. {
  105. if (Verbose) {
  106. fprintf(stderr, "=========================================================\n");
  107. fprintf(stderr, "%s started: %.24s (%lu) (%d)\n", Message.data(), ctime(&Begin), (unsigned long)Begin, (int)getpid());
  108. }
  109. }
  110. double TTimeLogger::ElapsedTime() const {
  111. return time(nullptr) - Begin;
  112. }
  113. void TTimeLogger::SetOK() {
  114. OK = true;
  115. }
  116. TTimeLogger::~TTimeLogger() {
  117. time_t tim = time(nullptr);
  118. ui64 endCycles = GetCycleCount();
  119. if (Verbose) {
  120. const char* prefix = (OK) ? "" : "!";
  121. fprintf(stderr, "%s%s ended: %.24s (%lu) (%d) (took %lus = %s)\n",
  122. prefix, Message.data(), ctime(&tim), (unsigned long)tim, (int)getpid(),
  123. (unsigned long)tim - (unsigned long)Begin, FormatCycles(endCycles - BeginCycles).data());
  124. fprintf(stderr, "%s=========================================================\n", prefix);
  125. }
  126. }