performance.cpp 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. // Copyright Oliver Kowalke 2014.
  2. // Distributed under the Boost Software License, Version 1.0.
  3. // (See accompanying file LICENSE_1_0.txt or copy at
  4. // http://www.boost.org/LICENSE_1_0.txt)
  5. #include <cstdlib>
  6. #include <iostream>
  7. #include <stdexcept>
  8. #include <string>
  9. #include <boost/chrono.hpp>
  10. #include <boost/coroutine2/all.hpp>
  11. #include <boost/cstdint.hpp>
  12. #include <boost/program_options.hpp>
  13. #include "bind_processor.hpp"
  14. #include "clock.hpp"
  15. #include "cycle.hpp"
  16. boost::uint64_t jobs = 1000;
  17. void fn( boost::coroutines2::coroutine< void >::push_type & c) {
  18. while ( true) {
  19. c();
  20. }
  21. }
  22. duration_type measure_time_void( duration_type overhead) {
  23. boost::coroutines2::coroutine< void >::pull_type c{ fn };
  24. time_point_type start( clock_type::now() );
  25. for ( std::size_t i = 0; i < jobs; ++i) {
  26. c();
  27. }
  28. duration_type total = clock_type::now() - start;
  29. total -= overhead_clock(); // overhead of measurement
  30. total /= jobs; // loops
  31. total /= 2; // 2x jump_fcontext
  32. return total;
  33. }
  34. # ifdef BOOST_CONTEXT_CYCLE
  35. cycle_type measure_cycles_void( cycle_type overhead) {
  36. boost::coroutines2::coroutine< void >::pull_type c{ fn };
  37. cycle_type start( cycles() );
  38. for ( std::size_t i = 0; i < jobs; ++i) {
  39. c();
  40. }
  41. cycle_type total = cycles() - start;
  42. total -= overhead; // overhead of measurement
  43. total /= jobs; // loops
  44. total /= 2; // 2x jump_fcontext
  45. return total;
  46. }
  47. # endif
  48. int main( int argc, char * argv[]) {
  49. try {
  50. bool bind = false;
  51. boost::program_options::options_description desc("allowed options");
  52. desc.add_options()
  53. ("help", "help message")
  54. ("bind,b", boost::program_options::value< bool >( & bind), "bind thread to CPU")
  55. ("jobs,j", boost::program_options::value< boost::uint64_t >( & jobs), "jobs to run");
  56. boost::program_options::variables_map vm;
  57. boost::program_options::store(
  58. boost::program_options::parse_command_line(
  59. argc,
  60. argv,
  61. desc),
  62. vm);
  63. boost::program_options::notify( vm);
  64. if ( vm.count("help") ) {
  65. std::cout << desc << std::endl;
  66. return EXIT_SUCCESS;
  67. }
  68. if ( bind) {
  69. bind_to_processor( 0);
  70. }
  71. duration_type overhead_c = overhead_clock();
  72. boost::uint64_t res = measure_time_void( overhead_c).count();
  73. std::cout << "average of " << res << " nano seconds" << std::endl;
  74. #ifdef BOOST_CONTEXT_CYCLE
  75. cycle_type overhead_y = overhead_cycle();
  76. res = measure_cycles_void( overhead_y);
  77. std::cout << "average of " << res << " cpu cycles" << std::endl;
  78. #endif
  79. return EXIT_SUCCESS;
  80. }
  81. catch ( std::exception const& e) {
  82. std::cerr << "exception: " << e.what() << std::endl;
  83. } catch (...) {
  84. std::cerr << "unhandled exception" << std::endl;
  85. }
  86. return EXIT_FAILURE;
  87. }