Skip to content

Instantly share code, notes, and snippets.

@owent
Created May 15, 2017 08:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save owent/110a4f73dd8def89e98d4cd66a0b8260 to your computer and use it in GitHub Desktop.
Save owent/110a4f73dd8def89e98d4cd66a0b8260 to your computer and use it in GitHub Desktop.
boost.context.callcc.benchmark
#!/bin/bash
# we assume boost (1.64 and upper) is installed in $BOOST_PREBUILT
BOOST_LIB_DIR=$BOOST_PREBUILT/lib;
g++ context_cc_text.cpp -O2 -g -ggdb -I$BOOST_PREBUILT/include -L$BOOST_LIB_DIR \
-lboost_context -lboost_system -lboost_thread -lboost_chrono \
-std=c++11 -o context_cc_text
#include <iostream>
#include <cstdlib>
#include <stdint.h>
#include <cstddef>
#include <cmath>
#include <ctime>
#include <cstring>
#include <boost/context/all.hpp>
#define CALC_MS_CLOCK(x) static_cast<int>((x) / (CLOCKS_PER_SEC / 1000))
#define CALC_NS_AVG_CLOCK(x, y) (1000000LL * static_cast<long long>((x) / (CLOCKS_PER_SEC / 1000)) / (y ? y : 1))
namespace ctx=boost::context;
class basic_stack {
public:
size_t size_;
void* p_;
public:
basic_stack(void* data, size_t sz):size_(sz), p_(data) {}
basic_stack(const basic_stack& other):size_(other.size_), p_(other.p_) {}
~basic_stack() {}
ctx::stack_context allocate() {
ctx::stack_context sctx;
sctx.size = size_;
sctx.sp = static_cast< char * >(p_) + sctx.size;
return sctx;
}
void deallocate( ctx::stack_context & sctx) {}
void free() {
::free(p_);
p_ = NULL;
size_ = 0;
}
};
int switch_count = 100;
std::vector<basic_stack> stack_arr;
std::vector<ctx::continuation> continuation_arr;
long long real_switch_times = 0;
ctx::continuation && call_instack_do_nothing(ctx::continuation && sink) {
int left_times = switch_count;
while(left_times -- > 0) {
++ real_switch_times;
sink = sink.resume();
}
++ real_switch_times;
return std::move(sink);
}
int caller_number = 100000; // 协程数量
static void benchmark_round(int index) {
real_switch_times = 0;
printf("### Round: %d ###\n", index);
time_t begin_time = time(NULL);
clock_t begin_clock = clock();
// yield & resume from runner
for (int i = 0; i < caller_number; ++i) {
continuation_arr.push_back(ctx::callcc<basic_stack, decltype(call_instack_do_nothing)>(std::allocator_arg, stack_arr[i], call_instack_do_nothing));
}
time_t end_time = time(NULL);
clock_t end_clock = clock();
printf("boost::context::callcc(create continuation) %d, cost time: %d s, clock time: %d ms, avg: %lld ns\n", caller_number,
static_cast<int>(end_time - begin_time), CALC_MS_CLOCK(end_clock - begin_clock),
CALC_NS_AVG_CLOCK(end_clock - begin_clock, continuation_arr.size()));
begin_time = end_time;
begin_clock = end_clock;
for(int k = 1; k < switch_count; ++ k) {
for (int i = 0; i < caller_number; ++i) {
continuation_arr[i] = continuation_arr[i].resume();
}
}
end_time = time(NULL);
end_clock = clock();
printf("boost::context::continuation.resume %d for %lld times, cost time: %d s, clock time: %d ms, avg: %lld ns\n", caller_number,
real_switch_times, static_cast<int>(end_time - begin_time), CALC_MS_CLOCK(end_clock - begin_clock),
CALC_NS_AVG_CLOCK(end_clock - begin_clock, real_switch_times));
continuation_arr.clear();
}
int main(int argc, char *argv[]) {
puts("###################### boost.context.continuation (stack using pool) ###################");
printf("########## Cmd:");
for (int i = 0; i < argc; ++i) {
printf(" %s", argv[i]);
}
puts("");
if (argc > 1) {
caller_number = atoi(argv[1]);
}
if (argc > 2) {
switch_count = atoi(argv[2]);
}
size_t stack_size = 64 * 1024;
if (argc > 3) {
stack_size = static_cast<size_t>(atoi(argv[3]));
}
stack_arr.reserve(caller_number);
continuation_arr.reserve(caller_number);
for (int i = 0; i < caller_number; ++ i) {
stack_arr.push_back(basic_stack(malloc(stack_size), stack_size));
}
for (int i = 1; i <= 8; ++i) {
benchmark_round(i);
}
for (int i = 0; i < caller_number; ++ i) {
stack_arr[i].free();
}
return 0;
}
# env LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$BOOST_PREBUILT/lib ./context_cc_text 1 100000000 16384
###################### boost.context.continuation (stack using pool) ###################
########## Cmd: ./context_cc_text 1 100000000 16384
### Round: 1 ###
boost::context::callcc(create continuation) 1, cost time: 0 s, clock time: 0 ms, avg: 0 ns
boost::context::continuation.resume 1 for 100000000 times, cost time: 1 s, clock time: 1450 ms, avg: 14 ns
### Round: 2 ###
boost::context::callcc(create continuation) 1, cost time: 0 s, clock time: 0 ms, avg: 0 ns
boost::context::continuation.resume 1 for 100000000 times, cost time: 2 s, clock time: 1420 ms, avg: 14 ns
### Round: 3 ###
boost::context::callcc(create continuation) 1, cost time: 0 s, clock time: 0 ms, avg: 0 ns
boost::context::continuation.resume 1 for 100000000 times, cost time: 1 s, clock time: 1420 ms, avg: 14 ns
### Round: 4 ###
boost::context::callcc(create continuation) 1, cost time: 0 s, clock time: 0 ms, avg: 0 ns
boost::context::continuation.resume 1 for 100000000 times, cost time: 1 s, clock time: 1420 ms, avg: 14 ns
### Round: 5 ###
boost::context::callcc(create continuation) 1, cost time: 0 s, clock time: 0 ms, avg: 0 ns
boost::context::continuation.resume 1 for 100000000 times, cost time: 2 s, clock time: 1410 ms, avg: 14 ns
### Round: 6 ###
boost::context::callcc(create continuation) 1, cost time: 0 s, clock time: 0 ms, avg: 0 ns
boost::context::continuation.resume 1 for 100000000 times, cost time: 1 s, clock time: 1410 ms, avg: 14 ns
### Round: 7 ###
boost::context::callcc(create continuation) 1, cost time: 0 s, clock time: 0 ms, avg: 0 ns
boost::context::continuation.resume 1 for 100000000 times, cost time: 2 s, clock time: 1420 ms, avg: 14 ns
### Round: 8 ###
boost::context::callcc(create continuation) 1, cost time: 0 s, clock time: 0 ms, avg: 0 ns
boost::context::continuation.resume 1 for 100000000 times, cost time: 1 s, clock time: 1420 ms, avg: 14 ns
# env LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$BOOST_PREBUILT/lib ./context_cc_text 30000 1000 16384
###################### boost.context.continuation (stack using pool) ###################
########## Cmd: ./context_cc_text 30000 1000 16384
### Round: 1 ###
boost::context::callcc(create continuation) 30000, cost time: 0 s, clock time: 10 ms, avg: 333 ns
boost::context::continuation.resume 30000 for 30000000 times, cost time: 2 s, clock time: 1990 ms, avg: 66 ns
### Round: 2 ###
boost::context::callcc(create continuation) 30000, cost time: 0 s, clock time: 10 ms, avg: 333 ns
boost::context::continuation.resume 30000 for 30000000 times, cost time: 2 s, clock time: 2000 ms, avg: 66 ns
### Round: 3 ###
boost::context::callcc(create continuation) 30000, cost time: 0 s, clock time: 10 ms, avg: 333 ns
boost::context::continuation.resume 30000 for 30000000 times, cost time: 2 s, clock time: 1980 ms, avg: 66 ns
### Round: 4 ###
boost::context::callcc(create continuation) 30000, cost time: 0 s, clock time: 0 ms, avg: 0 ns
boost::context::continuation.resume 30000 for 30000000 times, cost time: 2 s, clock time: 1990 ms, avg: 66 ns
### Round: 5 ###
boost::context::callcc(create continuation) 30000, cost time: 0 s, clock time: 10 ms, avg: 333 ns
boost::context::continuation.resume 30000 for 30000000 times, cost time: 2 s, clock time: 2060 ms, avg: 68 ns
### Round: 6 ###
boost::context::callcc(create continuation) 30000, cost time: 0 s, clock time: 10 ms, avg: 333 ns
boost::context::continuation.resume 30000 for 30000000 times, cost time: 2 s, clock time: 2030 ms, avg: 67 ns
### Round: 7 ###
boost::context::callcc(create continuation) 30000, cost time: 0 s, clock time: 10 ms, avg: 333 ns
boost::context::continuation.resume 30000 for 30000000 times, cost time: 2 s, clock time: 1930 ms, avg: 64 ns
### Round: 8 ###
boost::context::callcc(create continuation) 30000, cost time: 0 s, clock time: 10 ms, avg: 333 ns
boost::context::continuation.resume 30000 for 30000000 times, cost time: 2 s, clock time: 1930 ms, avg: 64 ns
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment