c++ - Boost ASIO async_write_some 真的很慢

标签 c++ networking boost boost-asio

我终于找到了我服务器的瓶颈,原来是async_writeasync_write_some也是如此。

这里是以下基准代码:

struct timespec start, end;
clock_gettime(CLOCK_MONOTONIC, &start);

//boost::asio::async_write(mMainData.mSocket, boost::asio::buffer(pSendBuff->pBuffer, pSendBuff->dwUsedSize), mMainData.mStrand.wrap(boost::bind(&CServer::WriteHandler, pServer, this, pSendBuff, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)));
mMainData.mSocket.async_write_some(boost::asio::buffer(pSendBuff->pBuffer, pSendBuff->dwUsedSize), (boost::bind(&CServer::WriteHandler, pServer, this, pSendBuff, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)));

clock_gettime(CLOCK_MONOTONIC, &end);

timespec temp;
if ((end.tv_nsec - start.tv_nsec) < 0)
{
    temp.tv_sec = end.tv_sec - start.tv_sec - 1;
    temp.tv_nsec = 1000000000 + end.tv_nsec - start.tv_nsec;
}
else
{
    temp.tv_sec = end.tv_sec - start.tv_sec;
    temp.tv_nsec = end.tv_nsec - start.tv_nsec;
}

pLogger->WriteToFile("./Logs/Benchmark_SendPacketP_AsyncWrite.txt", "dwDiff: %.4f\r\n", (float)temp.tv_nsec / 1000000.0f);

输出:

-[2016.05.21 03:45:19] dwDiff: 0.0552ms
-[2016.05.21 03:45:19] dwDiff: 0.0404ms
-[2016.05.21 03:45:19] dwDiff: 0.0542ms
-[2016.05.21 03:45:20] dwDiff: 0.0576ms

这太慢了,因为它是一个游戏服务器,我需要在房间 channel 中广播数据包,一个 channel 有 300 名玩家,想象一下它对我的玩家造成的网络延迟。

当然这个测试是在服务器上只有我自己完成的。

是我的代码错了还是我在 ASIO 实现逻辑中遗漏了什么?

CXXFLAGS: -ggdb -ffunction-sections -Ofast -m64 -pthread -fpermissive -w -lboost_system -lboost_thread -Wall -fomit-frame-pointer
LDFLAGS: -Wl,-gc-sections -m64 -pthread -fpermissive -w -lboost_system -lboost_thread -lcurl

硬件是: 英特尔至强 E3-1231v3(4 核 8 线程) 64GB 内存 1GBPS 上行链路

我正在培养 8 名 ASIO worker 。

所以我用调试器进入 async_write 并发现了这个:

template <typename ConstBufferSequence, typename Handler>
void async_send(base_implementation_type& impl,
  const ConstBufferSequence& buffers,
  socket_base::message_flags flags, Handler& handler)
{
bool is_continuation =
  boost_asio_handler_cont_helpers::is_continuation(handler);

// Allocate and construct an operation to wrap the handler.
typedef reactive_socket_send_op<ConstBufferSequence, Handler> op;
typename op::ptr p = { boost::asio::detail::addressof(handler),
  boost_asio_handler_alloc_helpers::allocate(
    sizeof(op), handler), 0 };
p.p = new (p.v) op(impl.socket_, buffers, flags, handler);

BOOST_ASIO_HANDLER_CREATION((p.p, "socket", &impl, "async_send"));

start_op(impl, reactor::write_op, p.p, is_continuation, true,
    ((impl.state_ & socket_ops::stream_oriented)
      && buffer_sequence_adapter<boost::asio::const_buffer,
        ConstBufferSequence>::all_empty(buffers)));
p.v = p.p = 0;
}

为什么 boost::asio 在本应是高性能的库中调用“new”? 无论如何要预先创建它试图分配的内容? 抱歉,我无法分析内部结构,因为我使用 VisualGDB 和 Microsoft Visual Studio 进行开发,并在 VMWare 中运行 GCC 4.8.5 工具集。

最佳答案

我知道这个答案有点晚了,但我会发布它以防有人觉得有用。

确实,在发布完成处理程序时会调用 new。然而,官方文档解释了如何通过实现自定义内存管理来优化以避免相关的运行时开销。这是示例: custom memory management for completion handlers

关于c++ - Boost ASIO async_write_some 真的很慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37358125/

相关文章:

.net - 如何减少网络上运行的 .Net dll 数量

c++ - 使用 Boost 和多线程中断进程

c++ - 工厂返回 boost::visitor 对象

c++ - 类似于用于 C++ 单元测试的 Google Test 的工具?

c++ - 'operator=' 和 sockaddr 成员的问题

c++ - ATI 卡上的片段着色器与 NVIDIA 卡上的片段着色器

javascript - Express 应用程序不响应外部流量

c++ - 从一对数组中获取匹配的元素 (C++/OpenCV)

算法 : Using maximum flow to calculate correct matrix values

c++ - 使用 boost::asio 创建定时器