Boost logo

Boost :

Subject: Re: [boost] [context review] Performance questions
From: Oliver Kowalke (oliver.kowalke_at_[hidden])
Date: 2012-01-09 14:22:01


Am 09.01.2012 19:35, schrieb Antony Polukhin:
> 1) What if we reimplement the ASIO example without Boost.Context
> (server class will look like this):
>
> class server : public boost::enable_shared_from_this< server>
> {
> private:
> boost::asio::ip::tcp::acceptor acceptor_;
> boost::array< char, 1024> buffer_;
>
> void do_()
> {
> boost::asio::ip::tcp::socket socket( acceptor_.get_io_service() );
> acceptor_.async_accept( socket, boost::bind(&
> server::do_1_, this->shared_from_this(), _1) );
> }
>
> void do_1_(boost::system::error_code ec)
> {
> if (!ec) {
> socket.async_read_some(
> boost::asio::buffer(buffer_),
> boost::bind(& server::do_2_,
> this->shared_from_this(), _1, _2) );
> } else {
> do_();
> }
> }
>
> void do_2_(boost::system::error_code ec, size_t n)
> if (!ec) {
> boost::asio::async_write(
> socket,
> boost::asio::buffer( buffer, n),
> boost::bind(& server::do_1_,
> this->shared_from_this(), _1) );
> } else {
> do_();
> }
> }
> }
>
> server( boost::asio::io_service& io_service, short port) :
> acceptor_( io_service, boost::asio::ip::tcp::endpoint(
> boost::asio::ip::tcp::v4(), port) ),
> {}
>
> public:
> typedef boost::shared_ptr< server> ptr_t;
>
> static ptr_t create( boost::asio::io_service& io_service, short port)
> { return ptr_t( new server( io_service, port) ); }
>
> void operator()( boost::system::error_code /*ec*/, size_t /*n*/)
> {
> do_();
> }
> };
>
> Looks like this implementation will be faster (it has the same amount
> of io_service posted functions, no dynamic allocations, but has no
> context switches). Am I missing something?

Beside the stack allocation (which could be preallocated and/or reused)
the boost.context function will not be slower.

With 'context switches' I don't mean context switches in the case of
threads!
'context switches' in boost.context consist of saving/restoring relevant
registers like stack pointer, instruction pointer, non-scratch registers
etc = the code generated by the compiler does the same (which registers
are saved/restored by a function call is defined by the 'call
convention' like cdecl etc.).

The ASIO example using boost.context is equivalent to using from
functions do_<xyz>_() in this sense.

The benefit in using boost.context is, that the code can be written more
straight forward. Your logic isn't scattered among several functions
(do_<xyz>_()).
I think Chris might explain this issue better than me in its article
'Thinking Asynchronously in C++' at
http://blog.think-async.com/2009/08/secret-sauce-revealed.html. I
adopted Chris example.

Oliver


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk