Ситуация:
Есть Windows. Есть некий протокол обмена сообщениями по TCP типа запрос ответ. Запрос порядка 512 байт. Ответ порядка 32К. Есть клиент и сервер. Клиент коннектится к серверу и начинает слать сообщения. Сервер обрабатывает сообщения строго последовательно одно после другого и его поведение мы изменить не можем.
На клиенте по одному соединение одновременно могут работать несколько потоков. Каждый поток работает по следующему алгоритму. Ставит свой запрос в очередь потока отправки и "садиться" ждать на событие. Поток отправки крутиться в цикле и последовательно отправляет запросы. Поток приема получает ответы, смотрит какому из потоков пришел ответ, копирует данные и пробуждает нужный клиенский поток.
Сейчас:
— скорость обработки одного запроса сервером порядка 0.0001
— скорость посылки и привема клиента порядка 0.001
Посоветуйте пожалуста можно как-то ускорить алгоритм работы клиета? Например как-нибудь отказаться от потоков отправки? Хотелось бы улучшить скорость на клиенте и попытаться сравнять со скоростью сервера. Кто — что может посоветовать?
Я встретил недавно такую схему в книге по UNIX. Для потоков обрабатывающих данные формируется одна очередь, а сообщения для них имеют идентификатор(в книге идентификатор конкретного потока, кому предназначены данные). Можно сделать примерно так: Потоки передают передающему потоку указатель на буфер размером 32 к, где в первых 4 байтах хранится идентификатор(допустим хандел, хотя сам указатель уже может являтся идентификатором), а дальше 512 байт сообщения. Передающий поток передаёт сообщение не с 0 а с 4 байта и принимает данные в этот же буфер начиная с 4 байта. Этот указатель ставится в очередь, которую выгребают потоки обрабатывающие данные. Один поток на передачу, один на прием не нужны, все равно протокол: запрос-ответ. Тут конечно главное избежать лишней обработки данных в потоке обмена.
Здравствуйте, AcidTheProgrammer, Вы писали:
ATP>Ситуация: ATP>Есть Windows. Есть некий протокол обмена сообщениями по TCP типа запрос ответ. Запрос порядка 512 байт. Ответ порядка 32К. Есть клиент и сервер. Клиент коннектится к серверу и начинает слать сообщения. Сервер обрабатывает сообщения строго последовательно одно после другого и его поведение мы изменить не можем. ATP>На клиенте по одному соединение одновременно могут работать несколько потоков. Каждый поток работает по следующему алгоритму. Ставит свой запрос в очередь потока отправки и "садится" ждать на событие. Поток отправки крутится в цикле и последовательно отправляет запросы. Поток приема получает ответы, смотрит какому из потоков пришел ответ, копирует данные и пробуждает нужный клиенский поток. ATP>Сейчас: ATP>- скорость обработки одного запроса сервером порядка 0.0001 ATP>- скорость посылки и привема клиента порядка 0.001
Это скорость в каких именно попугаях? Или это таки _время_ обработки (судя по комментариям ниже)? Прошу чётко разобраться хотя бы для себя самого в происходящем;)
ATP>Посоветуйте пожалуста можно как-то ускорить алгоритм работы клиета? Например как-нибудь отказаться от потоков отправки?
Можно, но неизвестно, станет ли от этого проще.
В качестве реального примера — innfeed (клиент) + innd (сервер). innfeed посылает в зависимости от доли принятых сервером статей или сразу статью целиком, или только её анонс, и копит очередь ответов (принята или не принята, для анонса — надо передавать или нет). Состояние общения с сервером — это в основном очереди. Кстати, разные сервера тоже обрабатываются одновременно одним тредом.
Но тут состояние клиента на один запрос крошечное (один message-id) и не нужно долгой истории. Перенесётся ли это на ваш случай, мне сейчас непонятно.
ATP> Хотелось бы улучшить скорость на клиенте и попытаться сравнять со скоростью сервера. Кто — что может посоветовать?
А от чего зависит скорость на клиенте? Может, ему просто нужно разбирать ответ и основное время уходит на это, а не на несчастное переключение в ожидании ответа? Или само ожидание (которое стоит только одного треда)?
Здравствуйте, netch80, Вы писали:
N>Это скорость в каких именно попугаях? Или это таки _время_ обработки (судя по комментариям ниже)? Прошу чётко разобраться хотя бы для себя самого в происходящем
Извеняюсь, забыл — это в секундах.
N>Можно, но неизвестно, станет ли от этого проще. N>В качестве реального примера — innfeed (клиент) + innd (сервер). innfeed посылает в зависимости от доли принятых сервером статей или сразу статью целиком, или только её анонс, и копит очередь ответов (принята или не принята, для анонса — надо передавать или нет). Состояние общения с сервером — это в основном очереди. Кстати, разные сервера тоже обрабатываются одновременно одним тредом.
Разные сессии в разных потоках конечно, но в рамках одной сессии все потоки лезут последовательно. Пока интересует только одна сессия, считайте один коннект в одном потоке.
N>Но тут состояние клиента на один запрос крошечное (один message-id) и не нужно долгой истории. Перенесётся ли это на ваш случай, мне сейчас непонятно.
N>А от чего зависит скорость на клиенте? Может, ему просто нужно разбирать ответ и основное время уходит на это, а не на несчастное переключение в ожидании ответа? Или само ожидание (которое стоит только одного треда)?
Разбирать ему конечно нужно, иначе зачем это все, но я замеряю только время посылки запроса и получения ответа. И только ускорение этого времени меня сейчас интересует. Т.е. считайте что обработка мгновенная.
Здравствуйте, AcidTheProgrammer, Вы писали:
N>>Это скорость в каких именно попугаях? Или это таки _время_ обработки (судя по комментариям ниже)? Прошу чётко разобраться хотя бы для себя самого в происходящем;) ATP>Извеняюсь, забыл — это в секундах.
То есть обратное скорости. Ясно.
ATP>Разные сессии в разных потоках конечно, но в рамках одной сессии все потоки лезут последовательно. Пока интересует только одна сессия, считайте один коннект в одном потоке.
Тогда Вам надо понимать, что измеренные скорости и времена исполнения принципиально отличаются на сервере и на клиенте. Сервер считает время от того, как пришёл запрос, до того, как он его отдал в сеть, и его не волнуют задержки (до тех пор, пока не начинается буквально кормёжка по байту). Запрос порядка 512 байт влезает в один IP пакет, поэтому задержки на приёме считай нет. Ответ попадает в сокетный буфер и уже оттуда медленно выливается в сеть. В случае же клиента подсчитанное время является временем, сколько запрос проходил через ядро на системе клиента, через сеть, через ядро на машине сервера, затем сколько сервер его обрабатывал, а затем обратный путь ответа, который существенно дольше, потому что в один пакет не влезает и надо ещё принять промежуточные подтверждения. В итоге получается, что на клиенте вы фактически меряете не время локальной обработки, а время проползания через сеть.
N>>А от чего зависит скорость на клиенте? Может, ему просто нужно разбирать ответ и основное время уходит на это, а не на несчастное переключение в ожидании ответа? Или само ожидание (которое стоит только одного треда)? ATP>Разбирать ему конечно нужно, иначе зачем это все, но я замеряю только время посылки запроса и получения ответа. И только ускорение этого времени меня сейчас интересует. Т.е. считайте что обработка мгновенная.
Тогда вам надо смириться, менять транспорт (не представляю себе пока, на что именно) или менять сам протокол, уменьшая количество необходимых запросов внутри сессии.
Здравствуйте, netch80, Вы писали:
N>Тогда Вам надо понимать, что измеренные скорости и времена исполнения принципиально отличаются на сервере и на клиенте. Сервер считает время от того, как пришёл запрос, до того, как он его отдал в сеть, и его не волнуют задержки (до тех пор, пока не начинается буквально кормёжка по байту). Запрос порядка 512 байт влезает в один IP пакет, поэтому задержки на приёме считай нет. Ответ попадает в сокетный буфер и уже оттуда медленно выливается в сеть. В случае же клиента подсчитанное время является временем, сколько запрос проходил через ядро на системе клиента, через сеть, через ядро на машине сервера, затем сколько сервер его обрабатывал, а затем обратный путь ответа, который существенно дольше, потому что в один пакет не влезает и надо ещё принять промежуточные подтверждения. В итоге получается, что на клиенте вы фактически меряете не время локальной обработки, а время проползания через сеть.
Спасибо, полностью с вами согласен, сам уже пришел точно к такому же выводу.
N>Тогда вам надо смириться, менять транспорт (не представляю себе пока, на что именно) или менять сам протокол, уменьшая количество необходимых запросов внутри сессии.
Посмотрел сколько времени это обычно занимает. В среднем порядка десятком микросекунд, так что походу дела из сокетов выжал все что можно. Думаю теперь заняться кешированием данных что бы минимизировать обращение к сети.