timer.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. /**
  2. \file timer.cpp
  3. \author michael.zohner@ec-spride.de
  4. \copyright ABY - A Framework for Efficient Mixed-protocol Secure Two-party Computation
  5. Copyright (C) 2019 ENCRYPTO Group, TU Darmstadt
  6. This program is free software: you can redistribute it and/or modify
  7. it under the terms of the GNU Lesser General Public License as published
  8. by the Free Software Foundation, either version 3 of the License, or
  9. (at your option) any later version.
  10. ABY is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU Lesser General Public License for more details.
  14. You should have received a copy of the GNU Lesser General Public License
  15. along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. \brief timer Implementation
  17. */
  18. #include <sys/time.h>
  19. #include <string>
  20. #include <iostream>
  21. #include <cstdlib>
  22. #include <vector>
  23. #include "timer.h"
  24. #include "constants.h"
  25. #include "socket.h"
  26. #include "typedefs.h"
  27. aby_timings m_tTimes[P_LAST - P_FIRST + 1];
  28. aby_comm m_tSend[P_LAST - P_FIRST + 1];
  29. aby_comm m_tRecv[P_LAST - P_FIRST + 1];
  30. double getMillies(timespec timestart, timespec timeend) {
  31. long time1 = (timestart.tv_sec * 1000000) + (timestart.tv_nsec / 1000);
  32. long time2 = (timeend.tv_sec * 1000000) + (timeend.tv_nsec / 1000);
  33. return (double) (time2 - time1) / 1000;
  34. }
  35. void StartWatch(const std::string& msg, ABYPHASE phase) {
  36. if (phase < P_FIRST || phase > P_LAST) {
  37. std::cerr << "Phase not recognized: " << phase << std::endl;
  38. return;
  39. }
  40. clock_gettime(CLOCK_MONOTONIC, &(m_tTimes[phase].tbegin));
  41. #ifndef BATCH
  42. std::cout << msg << std::endl;
  43. #else
  44. (void)msg; // silence -Wunused-parameter warning
  45. #endif
  46. }
  47. void StopWatch(const std::string& msg, ABYPHASE phase) {
  48. if (phase < P_FIRST || phase > P_LAST) {
  49. std::cerr << "Phase not recognized: " << phase << std::endl;
  50. return;
  51. }
  52. clock_gettime(CLOCK_MONOTONIC, &(m_tTimes[phase].tend));
  53. m_tTimes[phase].timing = getMillies(m_tTimes[phase].tbegin, m_tTimes[phase].tend);
  54. #ifndef BATCH
  55. std::cout << msg << m_tTimes[phase].timing << " ms " << std::endl;
  56. #else
  57. (void)msg; // silence -Wunused-parameter warning
  58. #endif
  59. }
  60. void StartRecording(const std::string& msg, ABYPHASE phase,
  61. const std::vector<std::unique_ptr<CSocket>>& sock) {
  62. StartWatch(msg, phase);
  63. m_tSend[phase].cbegin = 0;
  64. m_tRecv[phase].cbegin = 0;
  65. for(uint32_t i = 0; i < sock.size(); i++) {
  66. m_tSend[phase].cbegin += sock[i]->getSndCnt();
  67. m_tRecv[phase].cbegin += sock[i]->getRcvCnt();
  68. }
  69. }
  70. void StopRecording(const std::string& msg, ABYPHASE phase,
  71. const std::vector<std::unique_ptr<CSocket>>& sock) {
  72. StopWatch(msg, phase);
  73. m_tSend[phase].cend = 0;
  74. m_tRecv[phase].cend = 0;
  75. for(uint32_t i = 0; i < sock.size(); i++) {
  76. m_tSend[phase].cend += sock[i]->getSndCnt();
  77. m_tRecv[phase].cend += sock[i]->getRcvCnt();
  78. }
  79. m_tSend[phase].totalcomm = m_tSend[phase].cend - m_tSend[phase].cbegin;
  80. m_tRecv[phase].totalcomm = m_tRecv[phase].cend - m_tRecv[phase].cbegin;
  81. }
  82. void PrintTimings() {
  83. std::string unit = " ms";
  84. std::cout << "Timings: " << std::endl;
  85. std::cout << "Total =\t\t" << m_tTimes[P_TOTAL].timing << unit << std::endl;
  86. std::cout << "Init =\t\t" << m_tTimes[P_INIT].timing << unit << std::endl;
  87. std::cout << "CircuitGen =\t" << m_tTimes[P_CIRCUIT].timing << unit << std::endl;
  88. std::cout << "Network =\t" << m_tTimes[P_NETWORK].timing << unit << std::endl;
  89. std::cout << "BaseOTs =\t" << m_tTimes[P_BASE_OT].timing << unit << std::endl;
  90. std::cout << "Setup =\t\t" << m_tTimes[P_SETUP].timing << unit << std::endl;
  91. std::cout << "OTExtension =\t" << m_tTimes[P_OT_EXT].timing << unit << std::endl;
  92. std::cout << "Garbling =\t" << m_tTimes[P_GARBLE].timing << unit << std::endl;
  93. std::cout << "Online =\t" << m_tTimes[P_ONLINE].timing << unit << std::endl;
  94. }
  95. void PrintCommunication() {
  96. std::string unit = " bytes";
  97. std::cout << "Communication: " << std::endl;
  98. std::cout << "Total Sent / Rcv\t" << m_tSend[P_TOTAL].totalcomm << " " << unit << " / " << m_tRecv[P_TOTAL].totalcomm << unit << std::endl;
  99. std::cout << "BaseOTs Sent / Rcv\t" << m_tSend[P_BASE_OT].totalcomm << " " << unit << " / " << m_tRecv[P_BASE_OT].totalcomm << unit << std::endl;
  100. std::cout << "Setup Sent / Rcv\t" << m_tSend[P_SETUP].totalcomm << " " << unit << " / " << m_tRecv[P_SETUP].totalcomm << unit << std::endl;
  101. std::cout << "OTExtension Sent / Rcv\t" << m_tSend[P_OT_EXT].totalcomm << " " << unit << " / " << m_tRecv[P_OT_EXT].totalcomm << unit << std::endl;
  102. std::cout << "Garbling Sent / Rcv\t" << m_tSend[P_GARBLE].totalcomm << " " << unit << " / " << m_tRecv[P_GARBLE].totalcomm << unit << std::endl;
  103. std::cout << "Online Sent / Rcv\t" << m_tSend[P_ONLINE].totalcomm << " " << unit << " / " << m_tRecv[P_ONLINE].totalcomm << unit << std::endl;
  104. }