Падение производительности на порте с Beast.1.0.0-b66 до Boost.1.67.0. Beast - PullRequest
0 голосов
/ 25 апреля 2018

Я наблюдал резкое падение производительности (и резкое увеличение потребления процессора) при переходе с Beast.1.0.0-b66 (с использованием Boost.1.64.0) на Boost.1.67.0.Beast (т.е. с интегрированным Beastв Boost).Без сомнения, я сделал что-то не так, но я не могу себе представить, что.

Что было:

typedef beast::http::request<beast::http::string_body> BeastHttpRequest;

сейчас:

namespace http = boost::beast::http;    
typedef http::request<http::string_body> BeastHttpRequest;

и что было:

beast::http::prepare(req);
beast::http::write(stream, req);

сейчас:

req.prepare_payload();
http::write(stream, req);

Конечно, мне также пришлось внести многочисленные изменения в API.Например:

req.fields.replace(hdrName, hdrValue);

сейчас:

req.set(hdrName, hdrValue);

Приложение работает корректно - включая как подтверждение связи SSL, так и согласование прокси-сервера - но я должен исправить скачок в загрузке процессора исоразмерное падение производительности.Интересно, кто-нибудь знает что-то очевидное, что я упустил.

РЕДАКТИРОВАТЬ: я должен был упомянуть, что я использую flat_buffer для потока SSL.

У меня был шансдля профилирования данных производительности «до порта» и «после порта».Вот цепочка вызовов «до порта» (т.е. с хорошей производительностью):

- 34.61% HttpRequest::send
   - 32.02% beast::http::write<boost::asio::ssl::stream<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >&>, true, beast::http::string_body,
      - 31.90% beast::http::write<boost::asio::ssl::stream<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >&>, true, beast::http::string_bo
         - 20.77% beast::http::detail::write_preparation<true, beast::http::string_body, beast::http::basic_fields<std::allocator<char> > >::init
            - 18.25% beast::http::detail::write_fields<beast::basic_streambuf<std::allocator<char> >, beast::http::basic_fields<std::allocator<char> > >
               - 10.38% beast::write<beast::basic_streambuf<std::allocator<char> >, boost::basic_string_ref<char, std::char_traits<char> > >
                  - 10.20% beast::detail::write_dynabuf<beast::basic_streambuf<std::allocator<char> >, boost::basic_string_ref<char, std::char_traits<char> > >
                     + 3.66% beast::basic_streambuf<std::allocator<char> >::prepare
                     + 2.90% beast::basic_streambuf<std::allocator<char> >::commit
                     + 1.81% boost::lexical_cast<std::string, boost::basic_string_ref<char, std::char_traits<char> > >
                     + 1.47% boost::asio::buffer_copy<beast::basic_streambuf<std::allocator<char> >::mutable_buffers_type>
               - 7.51% beast::write<beast::basic_streambuf<std::allocator<char> >, char [3]>
                  - 7.47% beast::detail::write_dynabuf<beast::basic_streambuf<std::allocator<char> >, 3ul>
                     + 3.14% beast::basic_streambuf<std::allocator<char> >::prepare
                     + 2.84% beast::basic_streambuf<std::allocator<char> >::commit
                     + 1.32% boost::asio::buffer_copy<beast::basic_streambuf<std::allocator<char> >::mutable_buffers_type>
            + 2.04% beast::http::detail::write_start_line<beast::basic_streambuf<std::allocator<char> >, beast::http::basic_fields<std::allocator<char> > >
         - 9.60% beast::http::string_body::writer::write<beast::http::detail::writef0_lambda<boost::asio::ssl::stream<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_serv
            - 9.57% beast::http::detail::writef0_lambda<boost::asio::ssl::stream<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >&>, beast:
               - 9.54% boost::asio::write<boost::asio::ssl::stream<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >&>, beast::detail::buffe
                  - 9.48% boost::asio::write<boost::asio::ssl::stream<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >&>, beast::detail::bu
                     - 8.55% boost::asio::ssl::stream<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >&>::write_some<boost::asio::detail::c
                        - 7.56% boost::asio::ssl::detail::io<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >, boost::asio::ssl::detail::wr
                           - 6.98% boost::asio::write<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >, boost::asio::mutable_buffers_1>
                              - 6.93% boost::asio::write<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >, boost::asio::mutable_buffers_1,
                                 - 6.69% boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >::write_some<boost::asio::detail::consuming_buffer
                                    - 6.69% boost::asio::stream_socket_service<boost::asio::ip::tcp>::send<boost::asio::detail::consuming_buffers<boost::asio::const_buffer, boost::asio::mutable_buffers_1>
                                       - 6.67% boost::asio::detail::reactive_socket_service_base::send<boost::asio::detail::consuming_buffers<boost::asio::const_buffer, boost::asio::mutable_buffers_1> >
                                          - 6.51% boost::asio::detail::socket_ops::sync_send
                                             - 6.32% 0xec6d
                                                - 6.08% system_call_fastpath
                                                   - 6.07% sys_sendmsg
                                                      - 6.06% __sys_sendmsg
                                                         - 5.94% ___sys_sendmsg
                                                            + 5.84% sock_send

, а вот цепочка вызовов «после порта» (то есть с низкой производительностью):

- 53.77% HttpRequest::send
   - 53.32% boost::beast::http::write<boost::asio::ssl::stream<boost::asio::basic_stream_socket<boost::asio::ip::tcp>&>, true, boost::beast::http::basic_string_body<char, std::char_traits<char>, std::allo
      - 53.30% boost::beast::http::write<boost::asio::ssl::stream<boost::asio::basic_stream_socket<boost::asio::ip::tcp>&>, true, boost::beast::http::basic_string_body<char, std::char_traits<char>, std::a
         - 53.14% boost::beast::http::write<boost::asio::ssl::stream<boost::asio::basic_stream_socket<boost::asio::ip::tcp>&>, true, boost::beast::http::basic_string_body<char, std::char_traits<char>, std
            - 53.03% boost::beast::http::write_some<boost::asio::ssl::stream<boost::asio::basic_stream_socket<boost::asio::ip::tcp>&>, true, boost::beast::http::basic_string_body<char, std::char_traits<ch
               - 52.95% boost::beast::http::detail::write_some_impl<boost::asio::ssl::stream<boost::asio::basic_stream_socket<boost::asio::ip::tcp>&>, true, boost::beast::http::basic_string_body<char, std
                  - 36.58% boost::beast::http::serializer<true, boost::beast::http::basic_string_body<char, std::char_traits<char>, std::allocator<char> >, boost::beast::http::basic_fields<std::allocator<
                     - 35.28% boost::beast::http::serializer<true, boost::beast::http::basic_string_body<char, std::char_traits<char>, std::allocator<char> >, boost::beast::http::basic_fields<std::allocat
                        - 25.93% boost::beast::http::detail::write_some_lambda<boost::asio::ssl::stream<boost::asio::basic_stream_socket<boost::asio::ip::tcp>&> >::operator()<boost::beast::detail::buffers
                           - 25.82% boost::asio::ssl::stream<boost::asio::basic_stream_socket<boost::asio::ip::tcp>&>::write_some<boost::beast::detail::buffers_ref<boost::beast::buffers_prefix_view<boost:
                              - 25.69% boost::asio::ssl::detail::io<boost::asio::basic_stream_socket<boost::asio::ip::tcp>, boost::asio::ssl::detail::write_op<boost::beast::detail::buffers_ref<boost::beas
                                 - 22.20% boost::asio::write<boost::asio::basic_stream_socket<boost::asio::ip::tcp>, boost::asio::mutable_buffer>
                                    - 22.13% boost::asio::write<boost::asio::basic_stream_socket<boost::asio::ip::tcp>, boost::asio::mutable_buffer, boost::asio::detail::transfer_all_t>
                                       - 21.96% boost::asio::detail::write_buffer_sequence<boost::asio::basic_stream_socket<boost::asio::ip::tcp>, boost::asio::mutable_buffer, boost::asio::mutable_buffer
                                          - 21.47% boost::asio::basic_stream_socket<boost::asio::ip::tcp>::write_some<boost::asio::const_buffers_1>
                                             - 21.34% boost::asio::detail::reactive_socket_service_base::send<boost::asio::const_buffers_1>
                                                - 21.17% boost::asio::detail::socket_ops::sync_send
                                                   - 20.45% 0xec6d
                                                      - 19.63% system_call_fastpath
                                                         - 19.57% sys_sendmsg
                                                            - 19.52% __sys_sendmsg
                                                               - 19.16% ___sys_sendmsg
                                                                  + 18.90% sock_sendmsg

1 Ответ

0 голосов
/ 27 апреля 2018

Это должно быть быстрее, а не медленнее, так как алгоритмы HTTP были оптимизированы.Я думаю, что я знаю, что происходит, хотя.Было бы полезно сравнить производительность двух версий при использовании обычных сокетов, а не SSL.boost::asio::ssl::stream имеет недостаток, заключающийся в том, что при записи последовательностей буферов длиной более единицы он записывает данные в сокет для каждого буфера в последовательности вместо объединения этих зашифрованных буферов в одну запись.Это может оказать значительное влияние на производительность.

Это действительно необходимо исправить в Boost.Asio, но обходной путь заключается в том, что вы можете написать свою собственную потоковую оболочку с алгоритмом записи, когда она представлена ​​с последовательностями буферов, длина которых больше единицы, создает новую последовательность длиной один с использованием memcpy и динамического выделения.Я также открыл бы вопрос здесь: https://github.com/boostorg/asio/issues

Почему разница в двух версиях Beast?Старая версия Beast выделяла память во время сериализации для хранения линейной версии сообщения.Текущая версия использует алгоритм, который вообще не требует выделения памяти.В обычном случае это быстрее, но, как вы обнаружили при работе с ssl::stream типами, оно может быть медленнее.

См. https://github.com/boostorg/beast/issues/1108

...