
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