ограничение производительности asio :: async_write - PullRequest
0 голосов
/ 23 сентября 2019

Я разрабатываю сервер, используя asio для отправки данных по TCP.У меня есть реализация (вы можете увидеть посылку внизу вопроса), очень похожую на ту, которая была показана в этом ответе .

Я добавил некоторую меру измерения и заметил, что повышение ::Метод 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

на рабочем сервере (xeon E5-2687W v4 - WindowsServer 2016)

last 10000 => avg: 35742 - max:198656 - min:5462
last 10000 => avg: 34844 - max:178517 - min:7509
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...