2015-06-30 46 views
2

我正在使用Boost ASIO库来实现需要高吞吐量的Windows UDP客户端。如何增加Boost ASIO,UDP客户端应用程序的吞吐量

我想使用异步接收调用,以便我最终可以实现接收超时,即。如果没有收到数据报,经过一段时间后,我的应用程序将退出。

我的问题是,我看到使用同步接收器 比异步接收高30%的数据吞吐量。在多台Dell R630,R710 Windows 2008服务器,甚至是我的 联想ThinkPad笔记本电脑上运行 应用程序时,我发现了这个问题。

以下两个代码段的主要性能差异是什么? 在每个异步接收之后调用ioService.run_one()是否有更多开销? 我是Boost库的新用户,所以任何帮助将非常感谢!

同步接收:

socket_->receive_from(boost::asio::buffer(&vector_[0], datagramSize), 
         endPoint_); 

异步接收(用封闭):

err = boost::asio::error::would_block; 

socket_->async_receive_from(
    boost::asio::mutable_buffers_1(&vector_[0], datagramSize), 
    endPoint_, 
    boost::bind(&HandleRead, _1, _2, &err, &bytesReceived)); 

do 
{ 
    ioService_.run_one() 
} 
while(err == boost::asio::error::would_block) 

异步接收处理函数:

static void HandleRead 
(
    const boost::system::error_code& error, 
    std::size_t bytesRead, 
    boost::system::error_code* outError, 
    std::size_t* outBytesRead 
) 
{ 
    *outError = error; 
    *outBytesRead = bytesRead; 
} 
+0

在你async_receive_from情况下线程,处理器与缓慢标准'运营商new'分配。处理程序的快速[自定义分配](http://www.boost.org/doc/libs/1_58_0/doc/html/boost_asio/reference/asio_handler_allocate.html)可以提高性能。 –

回答

2

API函数族具有最重要的属性,它们异步运行并不令人惊讶。

异步运行任何东西本身并不会使其更快。事实上,由于安排文物,它可能会变慢。

问题是,异步可以让你在少数线程(例如主线程)上做更多的事情。

听起来有点像你的应用程序不需要多路复用类型的操作。如果您的应用程序确实以线性的方式尽可能快地消耗数据包的单一来源,比它确实是没有意义的

  • 介于A(线程安全的)任务队列
  • io_service跨调度任务可用的服务线程¹(您只有一个)
  • 以回调的形式回调结果;回调经常会导致对象生命周期的黑客攻击,而这往往会导致shared_ptr<> s。如果是这样,这些都是更多延迟的原因(由于参考地点的减少,更动态的分配等)。

如果您不需要它,请勿使用异步模式。

即使您的本质单线程顺序运行任务数量有限,也可以通过为每个线程分配一个线程并避免协调来实现最大效果。

¹运行io_service::run或类似