performance_create_prealloc.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  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 <cstdlib>
  6. #include <iostream>
  7. #include <stdexcept>
  8. #include <boost/chrono.hpp>
  9. #include <boost/coroutine/all.hpp>
  10. #include <boost/cstdint.hpp>
  11. #include <boost/program_options.hpp>
  12. #include "../bind_processor.hpp"
  13. #include "../clock.hpp"
  14. #include "../cycle.hpp"
  15. #include "../preallocated_stack_allocator.hpp"
  16. typedef preallocated_stack_allocator stack_allocator;
  17. typedef boost::coroutines::asymmetric_coroutine< void > coro_type;
  18. boost::coroutines::flag_fpu_t preserve_fpu = boost::coroutines::fpu_not_preserved;
  19. boost::coroutines::flag_unwind_t unwind_stack = boost::coroutines::stack_unwind;
  20. boost::uint64_t jobs = 1000;
  21. void fn( coro_type::push_type & c)
  22. { while ( true) c(); }
  23. duration_type measure_time( duration_type overhead)
  24. {
  25. stack_allocator stack_alloc;
  26. time_point_type start( clock_type::now() );
  27. for ( std::size_t i = 0; i < jobs; ++i) {
  28. coro_type::pull_type c( fn,
  29. boost::coroutines::attributes( unwind_stack, preserve_fpu),
  30. stack_alloc);
  31. }
  32. duration_type total = clock_type::now() - start;
  33. total -= overhead_clock(); // overhead of measurement
  34. total /= jobs; // loops
  35. return total;
  36. }
  37. # ifdef BOOST_CONTEXT_CYCLE
  38. cycle_type measure_cycles( cycle_type overhead)
  39. {
  40. stack_allocator stack_alloc;
  41. cycle_type start( cycles() );
  42. for ( std::size_t i = 0; i < jobs; ++i) {
  43. coro_type::pull_type c( fn,
  44. boost::coroutines::attributes( unwind_stack, preserve_fpu),
  45. stack_alloc);
  46. }
  47. cycle_type total = cycles() - start;
  48. total -= overhead; // overhead of measurement
  49. total /= jobs; // loops
  50. return total;
  51. }
  52. # endif
  53. int main( int argc, char * argv[])
  54. {
  55. try
  56. {
  57. bool preserve = false, unwind = true, bind = false;
  58. boost::program_options::options_description desc("allowed options");
  59. desc.add_options()
  60. ("help", "help message")
  61. ("bind,b", boost::program_options::value< bool >( & bind), "bind thread to CPU")
  62. ("fpu,f", boost::program_options::value< bool >( & preserve), "preserve FPU registers")
  63. ("unwind,u", boost::program_options::value< bool >( & unwind), "unwind coroutine-stack")
  64. ("jobs,j", boost::program_options::value< boost::uint64_t >( & jobs), "jobs to run");
  65. boost::program_options::variables_map vm;
  66. boost::program_options::store(
  67. boost::program_options::parse_command_line(
  68. argc,
  69. argv,
  70. desc),
  71. vm);
  72. boost::program_options::notify( vm);
  73. if ( vm.count("help") ) {
  74. std::cout << desc << std::endl;
  75. return EXIT_SUCCESS;
  76. }
  77. if ( preserve) preserve_fpu = boost::coroutines::fpu_preserved;
  78. if ( ! unwind) unwind_stack = boost::coroutines::no_stack_unwind;
  79. if ( bind) bind_to_processor( 0);
  80. duration_type overhead_c = overhead_clock();
  81. std::cout << "overhead " << overhead_c.count() << " nano seconds" << std::endl;
  82. boost::uint64_t res = measure_time( overhead_c).count();
  83. std::cout << "average of " << res << " nano seconds" << std::endl;
  84. #ifdef BOOST_CONTEXT_CYCLE
  85. cycle_type overhead_y = overhead_cycle();
  86. std::cout << "overhead " << overhead_y << " cpu cycles" << std::endl;
  87. res = measure_cycles( overhead_y);
  88. std::cout << "average of " << res << " cpu cycles" << std::endl;
  89. #endif
  90. return EXIT_SUCCESS;
  91. }
  92. catch ( std::exception const& e)
  93. { std::cerr << "exception: " << e.what() << std::endl; }
  94. catch (...)
  95. { std::cerr << "unhandled exception" << std::endl; }
  96. return EXIT_FAILURE;
  97. }