AUTH's THMMY "Parallel and distributed systems" course assignments.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

utils.hpp 4.3 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. /**
  2. * \file
  3. * \brief Utilities header
  4. *
  5. * \author
  6. * Christos Choutouridis AEM:8997
  7. * <cchoutou@ece.auth.gr>
  8. */
  9. #ifndef UTILS_HPP_
  10. #define UTILS_HPP_
  11. #include <vector>
  12. #include <iostream>
  13. #include <chrono>
  14. #include <unistd.h>
  15. #include <algorithm>
  16. #include "config.h"
  17. /*!
  18. * A Logger for entire program.
  19. */
  20. struct Log {
  21. struct Endl {} endl; //!< a tag object to to use it as a new line request.
  22. //! We provide logging via << operator
  23. template<typename T>
  24. Log &operator<<(T &&t) {
  25. if (config.verbose) {
  26. if (line_) {
  27. std::cout << "[Log]: " << t;
  28. line_ = false;
  29. } else
  30. std::cout << t;
  31. }
  32. return *this;
  33. }
  34. // overload for special end line handling
  35. Log &operator<<(Endl e) {
  36. (void) e;
  37. if (config.verbose) {
  38. std::cout << '\n';
  39. line_ = true;
  40. }
  41. return *this;
  42. }
  43. private:
  44. bool line_{true};
  45. };
  46. extern Log logger;
  47. /*!
  48. * A small timing utility based on chrono that supports timing rounds
  49. * and returning the median of them. Time can accumulate to the measurement
  50. * for each round.
  51. */
  52. struct Timing {
  53. using Tpoint = std::chrono::steady_clock::time_point;
  54. using Tduration = std::chrono::microseconds;
  55. using microseconds = std::chrono::microseconds;
  56. using milliseconds = std::chrono::milliseconds;
  57. using seconds = std::chrono::seconds;
  58. //! Setup measurement rounds
  59. void init(size_t rounds) {
  60. duration_.resize(rounds);
  61. for (auto& d : duration_)
  62. d = Tduration::zero();
  63. }
  64. //! tool to mark the starting point
  65. Tpoint start() noexcept { return mark_ = std::chrono::steady_clock::now(); }
  66. //! tool to mark the ending point
  67. Tpoint stop() noexcept {
  68. Tpoint now = std::chrono::steady_clock::now();
  69. duration_[current_] += dt(now, mark_);
  70. return now;
  71. }
  72. //! Switch timing slot
  73. void next() noexcept {
  74. ++current_;
  75. current_ %= duration_.size();
  76. }
  77. Tduration& median() noexcept {
  78. std::sort(duration_.begin(), duration_.end());
  79. return duration_[duration_.size()/2];
  80. }
  81. //! A duration calculation utility
  82. static Tduration dt(Tpoint t2, Tpoint t1) noexcept {
  83. return std::chrono::duration_cast<Tduration>(t2 - t1);
  84. }
  85. //! Tool to print the time interval
  86. static void print_duration(const Tduration& duration, const char *what) noexcept {
  87. if (std::chrono::duration_cast<microseconds>(duration).count() < 10000)
  88. std::cout << "[Timing] " << what << ": "
  89. << std::to_string(std::chrono::duration_cast<microseconds>(duration).count()) << " [usec]\n";
  90. else if (std::chrono::duration_cast<milliseconds>(duration).count() < 10000)
  91. std::cout << "[Timing] " << what << ": "
  92. << std::to_string(std::chrono::duration_cast<milliseconds>(duration).count()) << " [msec]\n";
  93. else {
  94. char stime[26]; // fit ulong
  95. auto sec = std::chrono::duration_cast<seconds>(duration).count();
  96. auto msec = (std::chrono::duration_cast<milliseconds>(duration).count() % 1000) / 10; // keep 2 digit
  97. std::sprintf(stime, "%ld.%1ld", sec, msec);
  98. std::cout << "[Timing] " << what << ": " << stime << " [sec]\n";
  99. }
  100. }
  101. private:
  102. size_t current_{0};
  103. Tpoint mark_{};
  104. std::vector<Tduration> duration_{1};
  105. };
  106. /*!
  107. * A "high level function"-like utility macro to forward a function call
  108. * and accumulate the execution time to the corresponding timing object.
  109. *
  110. * @param Tim The Timing object [Needs to have methods start() and stop()]
  111. * @param Func The function name
  112. * @param ... The arguments to pass to function (the preprocessor way)
  113. */
  114. #define timeCall(Tim, Func, ...) \
  115. Tim.start(); \
  116. Func(__VA_ARGS__); \
  117. Tim.stop(); \
  118. /*!
  119. * A utility to check if a number is power of two
  120. *
  121. * @tparam Integral The integral type of the number to check
  122. * @param x The number to check
  123. * @return True if it is power of 2, false otherwise
  124. */
  125. template <typename Integral>
  126. constexpr inline bool isPowerOfTwo(Integral x) noexcept {
  127. return (!(x & (x - 1)) && x);
  128. }
  129. #endif /* UTILS_HPP_ */