Created
September 20, 2017 03:04
-
-
Save jamboree/bb24a9cb5bff3622e276981b3f51be14 to your computer and use it in GitHub Desktop.
Compare Boost.Coroutine2/CO2/CoroutineTS
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Copyright Oliver Kowalke 2014. | |
// Distributed under the Boost Software License, Version 1.0. | |
// (See accompanying file LICENSE_1_0.txt or copy at | |
// http://www.boost.org/LICENSE_1_0.txt) | |
#include <cstdlib> | |
#include <iostream> | |
#include <stdexcept> | |
#include <string> | |
#include <boost/chrono.hpp> | |
#include <boost/coroutine2/all.hpp> | |
#include <boost/cstdint.hpp> | |
#include <co2/coroutine.hpp> | |
#include <experimental/coroutine> | |
#include "clock.hpp" | |
#include "cycle.hpp" | |
boost::uint64_t jobs = 1000; | |
namespace std { namespace experimental | |
{ | |
template<class... Ts> | |
struct coroutine_traits<coroutine_handle<>, Ts...> | |
{ | |
struct promise_type | |
{ | |
bool initial_suspend() noexcept | |
{ | |
return false; | |
} | |
bool final_suspend() noexcept | |
{ | |
return false; | |
} | |
coroutine_handle<> get_return_object() | |
{ | |
return coroutine_handle<promise_type>::from_promise(*this); | |
} | |
void return_void() noexcept {} | |
}; | |
}; | |
}} | |
void fn( boost::coroutines2::coroutine< void >::push_type & c) { | |
while ( true) { | |
c(); | |
} | |
} | |
auto fn_co2() CO2_BEG(co2::coroutine<>, ()) | |
{ | |
while (true) { | |
CO2_AWAIT(co2::suspend_always{}); | |
} | |
} CO2_END | |
std::experimental::coroutine_handle<> fn_std() | |
{ | |
while (true) { | |
co_await std::experimental::suspend_always{}; | |
} | |
} | |
template<class Coro> | |
duration_type measure_time_void(Coro& c, duration_type overhead) { | |
time_point_type start( clock_type::now() ); | |
for ( std::size_t i = 0; i < jobs; ++i) { | |
c(); | |
} | |
duration_type total = clock_type::now() - start; | |
total -= overhead; // overhead of measurement | |
total /= jobs; // loops | |
return total; | |
} | |
# ifdef BOOST_CONTEXT_CYCLE | |
template<class Coro> | |
cycle_type measure_cycles_void(Coro& c, cycle_type overhead) { | |
cycle_type start( cycles() ); | |
for ( std::size_t i = 0; i < jobs; ++i) { | |
c(); | |
} | |
cycle_type total = cycles() - start; | |
total -= overhead; // overhead of measurement | |
total /= jobs; // loops | |
return total; | |
} | |
# endif | |
int main( int argc, char * argv[]) { | |
try { | |
boost::coroutines2::coroutine< void >::pull_type c1{fn}; | |
auto c2 = fn_co2(); | |
auto c3 = fn_std(); | |
duration_type overhead_c = overhead_clock(); | |
boost::uint64_t res = measure_time_void(c1, overhead_c).count(); | |
std::cout << "average of " << res << " nano seconds" << std::endl; | |
res = measure_time_void(c2, overhead_c).count(); | |
std::cout << "average of " << res << " nano seconds" << std::endl; | |
res = measure_time_void(c3, overhead_c).count(); | |
std::cout << "average of " << res << " nano seconds" << std::endl; | |
#ifdef BOOST_CONTEXT_CYCLE | |
cycle_type overhead_y = overhead_cycle(); | |
res = measure_cycles_void(c1, overhead_y); | |
std::cout << "average of " << res << " cpu cycles" << std::endl; | |
res = measure_cycles_void(c2, overhead_y); | |
std::cout << "average of " << res << " cpu cycles" << std::endl; | |
res = measure_cycles_void(c3, overhead_y); | |
std::cout << "average of " << res << " cpu cycles" << std::endl; | |
c3.destroy(); | |
#endif | |
return EXIT_SUCCESS; | |
} | |
catch ( std::exception const& e) { | |
std::cerr << "exception: " << e.what() << std::endl; | |
} catch (...) { | |
std::cerr << "unhandled exception" << std::endl; | |
} | |
return EXIT_FAILURE; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment