首页 > 解决方案 > asio::async_write 性能限制

问题描述

我正在开发一个使用 asio 通过 tcp 发送数据的服务器。我有一个实现(您可以在问题底部看到发送)与此答案中公开的实现非常相似。

我添加了一些度量值并观察到 ​​boost::asio::async_send 方法有时需要很长时间。我期待(对此一无所知,只是期待)它应该会好很多,因为从我的角度来看,异步函数的 100 微秒似乎很多。

您可以在下面看到代码和一些测量示例,我做错了什么还是只是我的期望是错误的?

使用 msvc Visual Studio 2019 16.2.5 编译


std::vector<char> m_active_send_buffer_index[2];

    void do_send()
    {// Check if there is an async send in progress
        // An empty active buffer denotes no outstanding send
        if (m_stopped)
            return;

        if (m_send_buffers[m_active_send_buffer_index].size() == 0)
        {
            m_active_send_buffer_index ^= 1;//switch buffer

            auto self(this->shared_from_this());
            m_buffer_seq.push_back(boost::asio::buffer(m_send_buffers[m_active_send_buffer_index]));


            auto start = std::chrono::high_resolution_clock::now().time_since_epoch().count();
            boost::asio::async_write(m_socket, 
                    m_buffer_seq,
                    [self](const boost::system::error_code& error_code, size_t bytes_transferred)
                    {
                        std::lock_guard<std::mutex> lock(self->m_send_mutex);           
                        self->m_send_buffers[self->m_active_send_buffer_index].clear();
                        self->m_buffer_seq.clear();

                        if (!error_code)
                        {// no error occurred
                        // Check if there is more to send that has been queued up on the inactive buffer,
                        // while we were sending the active buffer

                            if (self->m_send_buffers[self->m_active_send_buffer_index ^ 1].size() > 0)
                            {
                                self->do_send();
                            }
                        }
                    }
                );
            auto stop = std::chrono::high_resolution_clock::now().time_since_epoch().count();
            static long count = 0;
            static long long time = 0;
            static long long max = 0;
            static long long min = 0xFFFFFFFF;
            static std::mutex mtx;
            mtx.lock();
            count++;
            long long t = stop - start;
            time += t;
            max = max < t ? t : max;
            min = min > t ? t : min;
            if (count == 10000)
            {
                std::cout << "last 10000 => avg: " << (time / 10000) << " - max:" << max << " - min:" << min << std::endl;
                count = 0; 
                time = 0;
                max = 0;
                min = 0xFFFFFFFF;
            }
            mtx.unlock();
        }
    }

这里有一些测量示例:

在我的台式机上(core i5 7400 - Windows10)

last 10000 => avg: 116434 - max:808700 - min:19200
last 10000 => avg: 120910 - max:1495700 - min:13100

在生产服务器上(至强 E5-2687W v4 - WindowsServer 2016)

last 10000 => avg: 35742 - max:198656 - min:5462
last 10000 => avg: 34844 - max:178517 - min:7509

标签: c++boost-asio

解决方案


推荐阅读