Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> реализация алгоритма 
:(
    Опции темы
boostcoder
Дата 9.11.2011, 09:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



всем бодрого утра.

итак. имеется протокол ввода-вывода. пакет состоит из заголовка фиксированного размера в котором содержится всякая инфа, размер тела данных, и, собственно, тело.
в данный момент, чтение пакета происходит следующим образом: 1)читается заголовок, 2)из заголовка узнается объем тела, 3)читается тело.

тут, мне не нравится то, что для чтения одного пакета приходится выполнять две операции чтения. а это довольно длинная цепь вызовов, в придачу, завершающаяся системным вызовом.

пришла такая идея: сторона, которая запрашивает данные, не должна читать их напрямую из сокета.
алгоритм: для каждого сокета выделяется буфер. для каждого буфера нужны два итератора: 1)итератор записи, 2)итератор чтения. сокет и буфер должны находится на одном уровне. условно, назовем этот уровень нижним. так же, у нас есть уровень, обращающийся к нижнему за данными. назовем его верхним уровнем.
начальное состояние: сокет открыт. буфер пуст. чтения не происходит.
итак. верхний уровень делает запрос к нижнему чтоб получить порцию данных. нижний уровень проверяет, имеется ли в буфере достаточно данных, и если да - верхнему уровню передается массив(пока не решил как, тупо копированием из буфера нижнего уровня в буфер верхнего, или путем передачи итератора(ов)). если это первое обращение за данными - выполняем запрос в сокет, и таким образом запускаем цикл пополнения буфера.
тут, нужен контроль следующих условий:
1. итератор чтения не должен перегнать итератор записи.
2. итератор записи не должен перегнать итератор чтения.

при такой реализации мы получаем следующую информацию основанную на позициях итераторов:
1. позиция итератора чтения нам говорит о том, сколько данных было прочтено.
2. дистанция от итератора чтения до итератора записи = объем доступных в буфере данных.
3. дистанция от итератора записи до итератора чтения = пространство доступное для записи.

при создании операции асинхронного чтения, в качестве буфера передаем итератор записи, а объем определяем согласно пункту 3 предыдущего параграфа.
операция асинхронного чтения читает из сокета все доступные данные, но не более чем было запрошено.

в общем, это изложение мысли как есть, без проработки и связи. наверняка что-то не учел, не додумал..


собственно тема создана для того, чтоб выслушать мнение форумчан, и, возможно, выявить "узкие" места и недочеты.


всем спасибо.

Это сообщение отредактировал(а) boostcoder - 9.11.2011, 11:10
PM WWW   Вверх
bsa
Дата 9.11.2011, 10:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Ты уверен, что именно на чтение сокета убивается большая часть ресурсов процессора? Что-то мне подсказывает, что это не так... Скажи, а как именно данные оправляются? Есть подозрение, что отправляются они так же, как принимаются - сначала заголовок, а затем тело. Таким образом, есть у меня подозрение, что сначала выполнится операция чтения, возвращающая только заголовок, а уже затем чтение тела, так как придут в разных пакетах... Или я не прав (в сетях я не большой гуру)?
PM   Вверх
boostcoder
Дата 9.11.2011, 10:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(bsa @  9.11.2011,  10:33 Найти цитируемый пост)
Ты уверен, что именно на чтение сокета убивается большая часть ресурсов процессора?

я бы не сказал что бОльшая..но порядочно. около 12 процентов.

Цитата(bsa @  9.11.2011,  10:33 Найти цитируемый пост)
сначала заголовок, а затем тело

не-не-не. отправка данных происходит за раз. с этим все нормально.

PM WWW   Вверх
mabrarov
Дата 9.11.2011, 11:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 100
Регистрация: 12.1.2011
Где: Казань

Репутация: 8
Всего: 9



Утра бодрого и Вам, boostcoder.
asio::buffered_read_stream и
asio::buffered_write_stream и, наконец, 
asio::buffered_stream.

Это позволит сэкономить на обращениях к сокету. В принципе, Вы этого и хотели. Но я предпочитаю иной вариант, потому что каждый async-запрос к buffered_stream все равно выливается в копии handler и пр. мелочевку. Для примера возьму чтение (алгоритм для записи выводим как-то по аналогии).

Итак, берем кольцевой буфер (ma::cyclic_buffer), размер которого >= максимальный размер сообщения (в идеале >>>). В каждой итерации пытаемся читать из сокета - (async_)read_some - столько, сколько есть/осталось свободного места в буфере. Отдельным объектом (class message_parser) парсим то, что считалось в буфер. При этом, на выходе message_parser::parse_some м/б [0..n] сообщений. message_parser есть КА и хранит текущее состояние парсинга с тем, чтобы при каждом последующем вызове не парсить всю последовательность с начала. Вообще в message_parser::parse_some каждый раз передаются только новые (вновь поступившие) данные (buffer_sequence или, точнее, ma::cyclic_buffer::const_buffers_type).

Если message_parser::parse_some (худший случай) длительный, то его можно проводить параллельно, но это уже больше похоже на извращение. Чтение (async_read_some) всегда выполняется в фоне. Т.е. сначала начинаем следующую итерацию чтения (start_async_read_some), а уже потом вызываем message_parser::parse_some. Поэтому, если уж message_parser::parse_some длительный, то эффективнее будет async_read_some + asio::null_buffers + неблокирующий режим. Такой режим, между прочим, считается последним спасением при высоких нагрузках и IOCP - видел англоязычную запись в каком-то блоге, посвященном IOCP и высоким нагрузкам (до сих пор найти не могу - может кто подскажет?).

Еще такой момент - все, что прошло через message_parser::parse_some, может 
1. считаться "свободным", т.е. освобождается в кольцевом буфере под запись новых данных (ma::cyclic_buffer::commit)
или 
2. message_parser::parse_some может дополнительно сообщать, сколько байт от начала переданной ему buffer_sequence можно считать "проглоченными парсером", т.е. "свободными".

Если не устраивает кольцевой буфер, то можно взять обычный. Но тогда в случае [2] (см. выше) нужно предусмотреть shift - сдвиг распарсенных, но не извлеченных из буфера данных в начало буфера с тем, чтобы обеспечить ненулевой свободный остаток в конце буфера. Можно делать сдвиг не всегда, а только в тех случаях, когда "свободный остаток в конце буфера" < threshold (я так и делал когда-то).

Все вышеописанное есть тот же самый buffered_stream, но с выделением логики парсинга из логики чтения. "100-пудов" это всем было известно и без меня. Но захотелось заодно и обсудить.

P.S. ma::cyclic_buffer.

Это сообщение отредактировал(а) mabrarov - 9.11.2011, 11:20
PM MAIL WWW Skype   Вверх
newbee
Дата 9.11.2011, 11:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бревно
**


Профиль
Группа: Участник
Сообщений: 703
Регистрация: 24.8.2011

Репутация: 4
Всего: 19



ОП прочла по диагонали, по-моему ты слишком усложняешь. Скорее всего цпу забивает процесс разбора пакета, а не чтения из сокета. Но даже если так, можно сделать много проще, ведь скорость обмена данными у тебя очень велика. Читаешь из сокета большой (в идеале заведомо больший, чем возможная максимальная длина пакета*) кусок данных, натравливаешь на него парсер.  Опять читаешь буфер, продолжаешь парсить, и т.д. Процесс можно пустить в два потока: один парсит имеющийся буфер, другой читает следующий буфер. Если парсер будет сильно не успевать за читалкой, можно сделать пул парсеров.

*под пакетом я имею в виду твой фрейм поверх IP/UDP/TCP/etc.


--------------------
You're face to face
With man who sold the world
PM   Вверх
mabrarov
Дата 9.11.2011, 11:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 100
Регистрация: 12.1.2011
Где: Казань

Репутация: 8
Всего: 9



Цитата(newbee @ 9.11.2011,  11:20)
ОП прочла по диагонали, по-моему ты слишком усложняешь. Скорее всего цпу забивает процесс разбора пакета, а не чтения из сокета. Но даже если так, можно сделать много проще, ведь скорость обмена данными у тебя очень велика. Читаешь из сокета большой (в идеале заведомо больший, чем возможная максимальная длина пакета*) кусок данных, натравливаешь на него парсер. ...

"Если что" (если я непонятно выразился), я имел в виду то же самое. У Вас получилось описать это проще smile

Это сообщение отредактировал(а) mabrarov - 9.11.2011, 11:29
PM MAIL WWW Skype   Вверх
newbee
Дата 9.11.2011, 11:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бревно
**


Профиль
Группа: Участник
Сообщений: 703
Регистрация: 24.8.2011

Репутация: 4
Всего: 19



mabrarov, когда я начинала писать, твоего сообщения еще не было. Так что это не плагиат smile


--------------------
You're face to face
With man who sold the world
PM   Вверх
mabrarov
Дата 9.11.2011, 11:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 100
Регистрация: 12.1.2011
Где: Казань

Репутация: 8
Всего: 9



Цитата(newbee @ 9.11.2011,  11:29)
mabrarov, когда я начинала писать, твоего сообщения еще не было. Так что это не плагиат smile

Да какой уж тут плагиат. Не "алгоритм Дейкстры" же. Просто у меня получилось запутанно. Вдруг кого смутит.
PM MAIL WWW Skype   Вверх
baldina
Дата 9.11.2011, 11:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 32
Всего: 101



Цитата(newbee @  9.11.2011,  11:20 Найти цитируемый пост)
Скорее всего цпу забивает процесс разбора пакета, а не чтения из сокета

те 12 процентов видимо из-за системного вызова, а не разбора заголовка.
тем не менее буферизация и параллельная работа с буфером мне кажется более удачной идеей чем прыжки с сокетами и итераторами
PM MAIL   Вверх
mabrarov
Дата 9.11.2011, 11:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 100
Регистрация: 12.1.2011
Где: Казань

Репутация: 8
Всего: 9



Цитата(baldina @ 9.11.2011,  11:40)
тем не менее буферизация и параллельная работа с буфером мне кажется более удачной идеей чем прыжки с сокетами и итераторами

То, что описал boostcoder, и еcть буферизация. Тот же самый asio::buffered_stream.
PM MAIL WWW Skype   Вверх
boostcoder
Дата 9.11.2011, 12:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(newbee @  9.11.2011,  11:20 Найти цитируемый пост)
Читаешь из сокета большой (в идеале заведомо больший, чем возможная максимальная длина пакета*)

нельзя читать больше, чем доступно для чтения без блокировки. иначе есть риск того, что я не смогу обработать первый пришедший пакет из-за того, что мы попросили прочитать 200 пакетов.

Цитата(newbee @  9.11.2011,  11:20 Найти цитируемый пост)
Скорее всего цпу забивает процесс разбора пакета

это тоже есть. и от этого не избавится.
я же хочу избавится от одного асинхронного чтения, что, по предсказанию профайлера, подарит мне более 12 процентов освободившихся ресурсов.

Цитата(baldina @  9.11.2011,  11:40 Найти цитируемый пост)
те 12 процентов видимо из-за системного вызова

угу. и из-за всего предшествующего. т.е. байндеры, io_service, new/delete, и т.д.

про asio::buffered_stream никогда не читал. почему-то...

в общем, сейчас "переварю" мысли/идеи....
PM WWW   Вверх
mabrarov
Дата 9.11.2011, 12:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 100
Регистрация: 12.1.2011
Где: Казань

Репутация: 8
Всего: 9



Цитата(boostcoder @ 9.11.2011,  12:07)
нельзя читать больше, чем доступно для чтения без блокировки. иначе есть риск того, что я не смогу обработать первый пришедший пакет из-за того, что мы попросили прочитать 200 пакетов.

У Вас async_read_some или async_read? async ли вообще? Потому что async-операции вполне позволяют Вам разбирать то, что уже пришло, параллельно чтению.

Это сообщение отредактировал(а) mabrarov - 9.11.2011, 12:27
PM MAIL WWW Skype   Вверх
boostcoder
Дата 9.11.2011, 12:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(mabrarov @  9.11.2011,  12:24 Найти цитируемый пост)
У Вас async_read_some или async_read?

async_read()
дело в том, что разбирать я начинаю в хендлере. а хендлер вызовется только тогда, когда будет прочитано указанное кол-во байт. т.е. к примеру мы указываем прочитать 200 байт, а в сокете есть только 100. так вот эти 100 я не могу обработать, потому что не вызывается хендлер.

тут наверное правильней использовать async_read_some()... значит нужно менять архитектуру.

Добавлено @ 13:04
почитал я asio::buffered_stream(если можно это назвать чтением)... в доке, вообще нет никакого описания поведения или принципа работы. ни каким образом получает данные, ни кто такой Arg  smile 
полез в исходники.

Это сообщение отредактировал(а) boostcoder - 9.1.2012, 15:49
PM WWW   Вверх
bsa
Дата 9.11.2011, 13:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Цитата(boostcoder @ 9.11.2011,  13:59)
почитал я asio::buffered_stream(если можно это назвать чтением)... в доке, вообще нет никакого описания поведения или принципа работы. ни каким образом получает данные, ни кто такой Arg  smile 
полез в исходники.

Я давно заметил, что Asio отличается особой полнотой и глубиной описания... Не то что всякие Qt...
PM   Вверх
mabrarov
Дата 9.11.2011, 13:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 100
Регистрация: 12.1.2011
Где: Казань

Репутация: 8
Всего: 9



Цитата(boostcoder @ 9.11.2011,  12:59)
почитал я asio::buffered_stream(если можно это назвать чтением)... в доке, вообще нет никакого описания поведения или принципа работы. ни каким образом получает данные, ни кто такой Arg  полез в исходники.

Вот именно эта часть вообще недокументированна. Вроде бы раньше это были служебные (внутренние для Asio) классы. Сам все хочу почитать их исходники, но никак не сделаю это последовательно и целиком.

Arg - это параметр для конструктора lower_layer. В случае, если lower_layer есть asio::ip::tcp::socket, то Arg - это asio::io_service&. Тут все аналогично asio::ssl::stream. Это вообще общая техника для оберток в Asio.

Добавлено @ 13:55
Цитата(bsa @ 9.11.2011,  13:23)
Я давно заметил, что Asio отличается особой полнотой и глубиной описания... Не то что всякие Qt...

Естественно. У Qt есть коммерческая версия + Trolltech/Nokia. Там есть кому писать и что платить "писателям". Ну напишете наконец Chris-у совместную "петицию" с указанием, что непонятно и где дописать/уточнить/поправить. В рассылке по Asio пока не было такого письма. В одной "российской" компании на Y мне (asio samples) сказали: "А чего там писать? И так все понятно - проще некуда".
И в Qt встречаются плохо документированные места. Попадалось использование !QObject raw pointer без объяснения, кто будет владеть ресурсом и кто будет его удалять/освобождать.

Добавлено @ 13:58
Цитата(boostcoder @ 9.11.2011,  12:59)
тут наверное правильней использовать async_read_some()... значит нужно менять архитектуру.

Можно попробовать asio::async_read + asio::transfer_at_least(минимальный размер пакета).
В той же компании Y не используют asio::async_xxx (мне так сказали - сам не проверял smile ) - только async_xxx_some. Видимо, они работают с таймаутами так же, как echo_server из asio samples - когда идет таймаут не на передачу n-го кол-ва данных, а таймаут на "активность". Т.е. если принят всего один байт, но он уложился в таймаут, то все ok - продолжаем держать соединение.

Это сообщение отредактировал(а) mabrarov - 9.11.2011, 14:10
PM MAIL WWW Skype   Вверх
boostcoder
Дата 9.11.2011, 14:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(mabrarov @  9.11.2011,  13:46 Найти цитируемый пост)
Arg - это параметр для конструктора lower_layer. В случае, если lower_layer есть asio::ip::tcp::socket, то Arg - это asio::io_service&. Тут все аналогично asio::ssl::stream. Это вообще общая техника для оберток в Asio.

да, уже разобрался. все просто.

Цитата(mabrarov @  9.11.2011,  13:46 Найти цитируемый пост)
Можно попробовать asio::async_read + asio::transfer_at_least(минимальный размер пакета).

тут нужно начать с написания теста по предыдущей реализации, и задуманной. этим и займусь.

и да, если с докой что-то не так, всегда можно исходники почитать. ну, на крайняк, самому написать доку и отослать автору патч. не думаю что он сильно расстроится.

Это сообщение отредактировал(а) boostcoder - 9.1.2012, 15:51
PM WWW   Вверх
mabrarov
Дата 9.11.2011, 14:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 100
Регистрация: 12.1.2011
Где: Казань

Репутация: 8
Всего: 9



Цитата(boostcoder @ 9.11.2011,  14:07)
Ну, на крайняк, самому написать доку и отослать автору патч. не думаю что он сильно расстроится.

Я бы на его месте поленился тащить такую ношу (+ несколько платформ) в одиночку да еще и бесплатно. Видимо, он что-то имеет с консультаций. Вроде что-то проскакивало про Австралию и custom-solution для гос/научного учреждения... Вот посмотрите на ACE. Сколько гос-бабла туда вбухали США? И как Вам документация (я уж молчу про код и что про него мне сказали в Y).
PM MAIL WWW Skype   Вверх
boostcoder
Дата 9.11.2011, 14:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(mabrarov @  9.11.2011,  14:20 Найти цитируемый пост)
И как Вам документация

дока ужасная, какой всегда и была, сколько я ее помню.
PM WWW   Вверх
boostcoder
Дата 16.4.2012, 07:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



вот только на один момент никто(?) не обратил внимания: используя asio::buffered_stream мы избавляемся от длиной цепочки вызовов и одного сискола, но взамен добавляем операцию копирования из asio::buffered_stream в передаваемый буфер. а это не малое копирование. это копирование всего трафика.
как считаете, будет ли такая оптимизация оправданна?


Это сообщение отредактировал(а) boostcoder - 16.4.2012, 07:17
PM WWW   Вверх
mabrarov
Дата 16.4.2012, 11:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 100
Регистрация: 12.1.2011
Где: Казань

Репутация: 8
Всего: 9



Цитата(boostcoder @ 16.4.2012,  07:16)
вот только на один момент никто(?) не обратил внимания: используя asio::buffered_stream мы избавляемся от длиной цепочки вызовов и одного сискола, но взамен добавляем операцию копирования из asio::buffered_stream в передаваемый буфер. а это не малое копирование. это копирование всего трафика.

А разве могло быть иначе?

Цитата(boostcoder @ 16.4.2012,  07:16)
как считаете, будет ли такая оптимизация оправданна?

Я думал, что на этом и последующих ответах тема себя исчерпала.
Это почти стандартный подход:
  • (циклический) буфер;
  • читаем (read_some) столько, сколько влезает в свободную часть буфера, т.е. стремимся сократить кол-во обращений к сокету - можно добавить asio::transfer_at_least(подсказка от парсера по минимальному кол-ву байт для завершения разбора очередного сообщения);
  • парсер входящих сообщений на КА;
  • копирование разобранного сообщения в отдельный объект и передача его через указатель (можно с shared-семантикой) дальше в логику обработки сообщений (еще один или несколько КА).


Это сообщение отредактировал(а) mabrarov - 16.4.2012, 11:29
PM MAIL WWW Skype   Вверх
boostcoder
Дата 16.4.2012, 13:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(mabrarov @  16.4.2012,  11:25 Найти цитируемый пост)
Я думал, что на этом и последующих ответах тема себя исчерпала.

я тоже так думал. но как дошел до реализации, одумался smile

PM WWW   Вверх
mabrarov
Дата 16.4.2012, 13:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 100
Регистрация: 12.1.2011
Где: Казань

Репутация: 8
Всего: 9



Цитата(boostcoder @ 16.4.2012,  13:03)
... но как дошел до реализации, одумался smile

Почему? Реализация описанного выше (буфер, чтение, парсер на КА, логика на КА) получается слишком запутанной? Или Вы написали это про asio::buffered_stream? 
IMHO: asio::buffered_stream не стоит тянуть в свои проекты. "Чтение с запасом + парсер-КА" универсальнее.

Это сообщение отредактировал(а) mabrarov - 16.4.2012, 14:02
PM MAIL WWW Skype   Вверх
boostcoder
Дата 16.4.2012, 18:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(mabrarov @  16.4.2012,  13:25 Найти цитируемый пост)
Реализация описанного выше (буфер, чтение, парсер на КА, логика на КА) получается слишком запутанной?

и это тоже. но основное - копирование всего трафа. но, как я понимаю, по другому быть не может. это я, хочу странного =)

КА мне тоже по идее не нужны. по сети будут передаваться массивы бинарного сериализатора. т.е. при прочтении, массив передается десериализатору.

Цитата(mabrarov @  16.4.2012,  13:25 Найти цитируемый пост)
IMHO: asio::buffered_stream не стоит тянуть в свои проекты.

по Вашему мнению, почему?

Цитата(mabrarov @  16.4.2012,  13:25 Найти цитируемый пост)
"Чтение с запасом + парсер-КА" универсальнее.

объясните плиз более развернуто, для чего тут КА и кем является "парсер"?

PM WWW   Вверх
mabrarov
Дата 16.4.2012, 20:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 100
Регистрация: 12.1.2011
Где: Казань

Репутация: 8
Всего: 9



Цитата(boostcoder @ 16.4.2012,  18:56)
и это тоже. но основное - копирование всего трафа. но, как я понимаю, по другому быть не может. это я, хочу странного =)

Это возможно, когда десериализация не требует ничего кроме копирования. Тогда по заголовку сообщения можно сразу выделять буфер нужного размера и тогда же не удастся сэкономить на обращениях к сокету.

Цитата(boostcoder @ 16.4.2012,  18:56)

КА мне тоже по идее не нужны. по сети будут передаваться массивы бинарного сериализатора. т.е. при прочтении, массив передается десериализатору.

У нас наметилось явное недопонимание: 
парсер == десериализатор.

Цитата(boostcoder @ 16.4.2012,  18:56)
Цитата(mabrarov @  16.4.2012,  13:25 Найти цитируемый пост)
IMHO: asio::buffered_stream не стоит тянуть в свои проекты.
по Вашему мнению, почему?

Потому что это лишнее, если Ваш десериализатор умеет парсить данные из буфера приема и может продолжать парсить частично полученные сообщения. Обработка того же протокола заголовок-с-размером-тела+тело - есть простейший парсер/десериализатор.. в книжках по ACE эту часть называют... эээ... frame protocol, что ли.
PM MAIL WWW Skype   Вверх
boostcoder
Дата 17.4.2012, 02:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(mabrarov @  16.4.2012,  20:16 Найти цитируемый пост)
Это возможно, когда десериализация не требует ничего кроме копирования. Тогда по заголовку сообщения можно сразу выделять буфер нужного размера и тогда же не удастся сэкономить на обращениях к сокету.

что-то я совсем запутался %)

сначала я запрашиваю у сокета прочитать заголовок. из него я узнаю размер тела. и делаю еще один запрос на чтение тела.
это сейчас так. и тут у нас проблема с двумя цепочками вызовов для получения одного пакета.

если решать эту проблему с помощью буферизированного сокета - логика остается та же. но разница в том, что для прочтения тела не всегда будет производится сискол аж на уровень сокета, ибо тело может быть уже в буфере.
таким образом, мы сэкономим на сисколе, но вся цепь вызовов до него все равно будет выполняться.

к тому же, то, что я описал в топике, не предполагало копирование всего трафа, ибо там я предполагал передавать итераторы.
как-то так:
Код

socket s(...);
buffer b(s); // но нам не известен заранее максимальный размер буфера

...

int header = 0;
b.async_read(
   sizeof(header),
   [](const char *ptr, size_t size, error_code e) {
      // ptr - указатель на буфер
      из ptr получаем размер тела...
      ...
      b.async_read(
         header,
         [](const char *ptr, size_t size, error_code e) {
            все! получили тело!
            десериализуем.
         }
      );
   }
);



Это сообщение отредактировал(а) boostcoder - 17.4.2012, 03:12
PM WWW   Вверх
boostcoder
Дата 17.4.2012, 03:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



я думаю скопипастить реализацию asio::buffered_read_stream и переделать ее для работы с итераторами...

Добавлено через 3 минуты и 34 секунды
проблему неизвестного максимального размера буфера, я думаю, можно решить дополнительным буфером, который будет создаваться если запрошен размер превышающий максимальный размер дефолтного буфера.
большинство пакетов имеют размер до 20ти байт.

PM WWW   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0755 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.