performance.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. // Copyright Oliver Kowalke 2009.
  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 <cstddef>
  6. #include <cstdlib>
  7. #include <iostream>
  8. #include <stdexcept>
  9. #include <boost/context/fiber.hpp>
  10. #include <boost/cstdint.hpp>
  11. #include <boost/program_options.hpp>
  12. #include "../clock.hpp"
  13. #include "../cycle.hpp"
  14. boost::uint64_t jobs = 1000000;
  15. namespace ctx = boost::context;
  16. static ctx::fiber foo( ctx::fiber && f) {
  17. while ( true) {
  18. f = std::move( f).resume();
  19. }
  20. return ctx::fiber{};
  21. }
  22. duration_type measure_time() {
  23. // cache warum-up
  24. ctx::fiber f{ foo };
  25. f = std::move( f).resume();
  26. time_point_type start( clock_type::now() );
  27. for ( std::size_t i = 0; i < jobs; ++i) {
  28. f = std::move( f).resume();
  29. }
  30. duration_type total = clock_type::now() - start;
  31. total -= overhead_clock(); // overhead of measurement
  32. total /= jobs; // loops
  33. total /= 2; // 2x jump_fcontext
  34. return total;
  35. }
  36. #ifdef BOOST_CONTEXT_CYCLE
  37. cycle_type measure_cycles() {
  38. // cache warum-up
  39. ctx::fixedsize_stack alloc;
  40. ctx::fiber f{ std::allocator_arg, alloc, foo };
  41. f = std::move( f).resume();
  42. cycle_type start( cycles() );
  43. for ( std::size_t i = 0; i < jobs; ++i) {
  44. f = std::move( f).resume();
  45. }
  46. cycle_type total = cycles() - start;
  47. total -= overhead_cycle(); // overhead of measurement
  48. total /= jobs; // loops
  49. total /= 2; // 2x jump_fcontext
  50. return total;
  51. }
  52. #endif
  53. int main( int argc, char * argv[]) {
  54. try {
  55. boost::program_options::options_description desc("allowed options");
  56. desc.add_options()
  57. ("help", "help message")
  58. ("jobs,j", boost::program_options::value< boost::uint64_t >( & jobs), "jobs to run");
  59. boost::program_options::variables_map vm;
  60. boost::program_options::store(
  61. boost::program_options::parse_command_line(
  62. argc,
  63. argv,
  64. desc),
  65. vm);
  66. boost::program_options::notify( vm);
  67. if ( vm.count("help") ) {
  68. std::cout << desc << std::endl;
  69. return EXIT_SUCCESS;
  70. }
  71. boost::uint64_t res = measure_time().count();
  72. std::cout << "fiber: average of " << res << " nano seconds" << std::endl;
  73. #ifdef BOOST_CONTEXT_CYCLE
  74. res = measure_cycles();
  75. std::cout << "fiber: average of " << res << " cpu cycles" << std::endl;
  76. #endif
  77. return EXIT_SUCCESS;
  78. } catch ( std::exception const& e) {
  79. std::cerr << "exception: " << e.what() << std::endl;
  80. } catch (...) {
  81. std::cerr << "unhandled exception" << std::endl;
  82. }
  83. return EXIT_FAILURE;
  84. }