mon_stats.h 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. #pragma once
  2. #include "defs.h"
  3. #include "actor.h"
  4. #include <library/cpp/monlib/metrics/histogram_snapshot.h>
  5. #include <util/system/hp_timer.h>
  6. namespace NActors {
  7. struct TLogHistogram : public NMonitoring::IHistogramSnapshot {
  8. TLogHistogram() {
  9. memset(Buckets, 0, sizeof(Buckets));
  10. }
  11. inline void Add(ui64 val, ui64 inc = 1) {
  12. size_t ind = 0;
  13. #if defined(__clang__) && __clang_major__ == 3 && __clang_minor__ == 7
  14. asm volatile("" ::
  15. : "memory");
  16. #endif
  17. if (val > 1) {
  18. ind = GetValueBitCount(val - 1);
  19. }
  20. #if defined(__clang__) && __clang_major__ == 3 && __clang_minor__ == 7
  21. asm volatile("" ::
  22. : "memory");
  23. #endif
  24. RelaxedStore(&TotalSamples, RelaxedLoad(&TotalSamples) + inc);
  25. RelaxedStore(&Buckets[ind], RelaxedLoad(&Buckets[ind]) + inc);
  26. }
  27. void Aggregate(const TLogHistogram& other) {
  28. const ui64 inc = RelaxedLoad(&other.TotalSamples);
  29. RelaxedStore(&TotalSamples, RelaxedLoad(&TotalSamples) + inc);
  30. for (size_t i = 0; i < Y_ARRAY_SIZE(Buckets); ++i) {
  31. Buckets[i] += RelaxedLoad(&other.Buckets[i]);
  32. }
  33. }
  34. // IHistogramSnapshot
  35. ui32 Count() const override {
  36. return Y_ARRAY_SIZE(Buckets);
  37. }
  38. NMonitoring::TBucketBound UpperBound(ui32 index) const override {
  39. Y_ASSERT(index < Y_ARRAY_SIZE(Buckets));
  40. if (index == 0) {
  41. return 1;
  42. }
  43. return NMonitoring::TBucketBound(1ull << (index - 1)) * 2.0;
  44. }
  45. NMonitoring::TBucketValue Value(ui32 index) const override {
  46. Y_ASSERT(index < Y_ARRAY_SIZE(Buckets));
  47. return Buckets[index];
  48. }
  49. ui64 TotalSamples = 0;
  50. ui64 Buckets[65];
  51. };
  52. struct TExecutorPoolStats {
  53. ui64 MaxUtilizationTime = 0;
  54. };
  55. struct TExecutorThreadStats {
  56. ui64 SentEvents = 0;
  57. ui64 ReceivedEvents = 0;
  58. ui64 PreemptedEvents = 0; // Number of events experienced hard preemption
  59. ui64 NonDeliveredEvents = 0;
  60. ui64 EmptyMailboxActivation = 0;
  61. ui64 CpuNs = 0; // nanoseconds thread was executing on CPU (accounts for preemtion)
  62. NHPTimer::STime ElapsedTicks = 0;
  63. NHPTimer::STime ParkedTicks = 0;
  64. NHPTimer::STime BlockedTicks = 0;
  65. TLogHistogram ActivationTimeHistogram;
  66. TLogHistogram EventDeliveryTimeHistogram;
  67. TLogHistogram EventProcessingCountHistogram;
  68. TLogHistogram EventProcessingTimeHistogram;
  69. TVector<NHPTimer::STime> ElapsedTicksByActivity;
  70. TVector<ui64> ReceivedEventsByActivity;
  71. TVector<i64> ActorsAliveByActivity; // the sum should be positive, but per-thread might be negative
  72. TVector<ui64> ScheduledEventsByActivity;
  73. ui64 PoolActorRegistrations = 0;
  74. ui64 PoolDestroyedActors = 0;
  75. ui64 PoolAllocatedMailboxes = 0;
  76. ui64 MailboxPushedOutBySoftPreemption = 0;
  77. ui64 MailboxPushedOutByTime = 0;
  78. ui64 MailboxPushedOutByEventCount = 0;
  79. TExecutorThreadStats(size_t activityVecSize = 1) // must be not empty as 0 used as default
  80. : ElapsedTicksByActivity(activityVecSize)
  81. , ReceivedEventsByActivity(activityVecSize)
  82. , ActorsAliveByActivity(activityVecSize)
  83. , ScheduledEventsByActivity(activityVecSize)
  84. {}
  85. template <typename T>
  86. static void AggregateOne(TVector<T>& self, const TVector<T>& other) {
  87. const size_t selfSize = self.size();
  88. const size_t otherSize = other.size();
  89. if (selfSize < otherSize)
  90. self.resize(otherSize);
  91. for (size_t at = 0; at < otherSize; ++at)
  92. self[at] += RelaxedLoad(&other[at]);
  93. }
  94. void Aggregate(const TExecutorThreadStats& other) {
  95. SentEvents += RelaxedLoad(&other.SentEvents);
  96. ReceivedEvents += RelaxedLoad(&other.ReceivedEvents);
  97. PreemptedEvents += RelaxedLoad(&other.PreemptedEvents);
  98. NonDeliveredEvents += RelaxedLoad(&other.NonDeliveredEvents);
  99. EmptyMailboxActivation += RelaxedLoad(&other.EmptyMailboxActivation);
  100. CpuNs += RelaxedLoad(&other.CpuNs);
  101. ElapsedTicks += RelaxedLoad(&other.ElapsedTicks);
  102. ParkedTicks += RelaxedLoad(&other.ParkedTicks);
  103. BlockedTicks += RelaxedLoad(&other.BlockedTicks);
  104. MailboxPushedOutBySoftPreemption += RelaxedLoad(&other.MailboxPushedOutBySoftPreemption);
  105. MailboxPushedOutByTime += RelaxedLoad(&other.MailboxPushedOutByTime);
  106. MailboxPushedOutByEventCount += RelaxedLoad(&other.MailboxPushedOutByEventCount);
  107. ActivationTimeHistogram.Aggregate(other.ActivationTimeHistogram);
  108. EventDeliveryTimeHistogram.Aggregate(other.EventDeliveryTimeHistogram);
  109. EventProcessingCountHistogram.Aggregate(other.EventProcessingCountHistogram);
  110. EventProcessingTimeHistogram.Aggregate(other.EventProcessingTimeHistogram);
  111. AggregateOne(ElapsedTicksByActivity, other.ElapsedTicksByActivity);
  112. AggregateOne(ReceivedEventsByActivity, other.ReceivedEventsByActivity);
  113. AggregateOne(ActorsAliveByActivity, other.ActorsAliveByActivity);
  114. AggregateOne(ScheduledEventsByActivity, other.ScheduledEventsByActivity);
  115. RelaxedStore(
  116. &PoolActorRegistrations,
  117. std::max(RelaxedLoad(&PoolActorRegistrations), RelaxedLoad(&other.PoolActorRegistrations)));
  118. RelaxedStore(
  119. &PoolDestroyedActors,
  120. std::max(RelaxedLoad(&PoolDestroyedActors), RelaxedLoad(&other.PoolDestroyedActors)));
  121. RelaxedStore(
  122. &PoolAllocatedMailboxes,
  123. std::max(RelaxedLoad(&PoolAllocatedMailboxes), RelaxedLoad(&other.PoolAllocatedMailboxes)));
  124. }
  125. size_t MaxActivityType() const {
  126. return ActorsAliveByActivity.size();
  127. }
  128. };
  129. }