Skip to content

Instantly share code, notes, and snippets.

@jamboree
Created September 20, 2017 03:04
Show Gist options
  • Save jamboree/bb24a9cb5bff3622e276981b3f51be14 to your computer and use it in GitHub Desktop.
Save jamboree/bb24a9cb5bff3622e276981b3f51be14 to your computer and use it in GitHub Desktop.
Compare Boost.Coroutine2/CO2/CoroutineTS
// 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