cputimer.cpp 3.7 KB

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