|
Модераторы: Daevaorn |
|
boostcoder |
|
||||
pattern`щик Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
всем доброго вечера.
хочу написать обертку над asio сокетом, дабы улучшить юзабильность. хочу избавиться от ручного написания байнда и хранения записываемого буфера до окончания асинхронной операции. это и хочу обсудить. сейчас вижу интерфейс таким:
чтоб использовать так:
первый вопрос - есть ли смысл вообще в обертке? второй вопрос - в случае записи указателя на char, есть ли смысл копировать данные в какой-то внутренний буфер обертки? или просто запоминать указатель, по при вызове хэндлера - освобождать память на которую он указывает? третий вопрос - что вообще нужно такой обертке, и что не нужно? спасибо. |
||||
|
|||||
borisbn |
|
||||
Эксперт Профиль Группа: Завсегдатай Сообщений: 4875 Регистрация: 6.2.2010 Где: Ростов-на-Дону Репутация: 22 Всего: 135 |
думаю есть, т.к. довольно часто приходится делать одно и то же, наступать на те же грабли, копипастить... брррр IMHO однозначно копировать. чтобы не получилось такой ситуации
IMHO лучше интерфеса, чем этот не придумаешь Это сообщение отредактировал(а) borisbn - 10.4.2011, 23:53 -------------------- Женщины отличаются от программистов тем, что у них чары состоят из стрингов |
||||
|
|||||
bsa |
|
||||
Эксперт Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
|
||||
|
|||||
boostcoder |
|
|||
pattern`щик Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
допустим... тогда встает вопрос о размере внутреннего буфера обертки. 1. должен указываться в конструкторе? 2. или увеличивается столько, сколько свободной памяти на машине? 3. расходы на выделение памяти/копирование не пугают? у меня есть такое предложение: обязать пользователя передавать в сокет смарт_поинтер инициализированный/заполненный юзером. в этом есть есть два плюса: 1. не нужно ничего копировать. т.к. внутренний буфер становится очередью из смарт_поинтеров 2. не нужно руками освобождать память. |
|||
|
||||
mes |
|
|||
любитель Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
||||
|
||||
borisbn |
|
||||||||
Эксперт Профиль Группа: Завсегдатай Сообщений: 4875 Регистрация: 6.2.2010 Где: Ростов-на-Дону Репутация: 22 Всего: 135 |
IMHO некрасиво
внутренний буфер будет увеличиваться только в том случае, если юзер будет подавать данные быстрее, чем они будут уходить получателю... Если юзер так рассчитал систему - то он сам виноват. Библиотека (обёртка) тут не при чём. Думаю, что сама отправка (скорость передачи по каналу) будет на порядки дольше, чем обращение к менеджеру памяти и копирование из одной области памяти в другую. Даже если передача данных будет происходить по 127.0.0.1
В этом случае юзерская ф-ция отправки, например, строки будет выглядеть некрасиво
вместо
-------------------- Женщины отличаются от программистов тем, что у них чары состоят из стрингов |
||||||||
|
|||||||||
boostcoder |
|
||||||||||||
pattern`щик Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
тут Вы ошибаетесь. в этой теме, возьмите последние исходники и посмотрите. там очень простой код. выделение 13 байт, sprintf(), передача в async_write(), в хэндлере delete[]. ничего сложного ведь ;) но на 100мбитной сети, происходит 220000-250000 таких последовательностей, что полносьтю загружает одно ядро. вроде бы казалось, ничего сложного в этих операциях нет. но профайлер говорит что 48 процентов времени уходит только на new! в общем, выделение памяти и инициализацию смарт_поинтера оставил на юзера. помоему, очень даже юзабельно получилось пожелания/рекомендации/критика приветствуются. класс сокета:
пример 1:
пример 2:
пример 3:
всем спасибо Добавлено через 6 минут и 9 секунд
не нравится постоянно писать байнд. в добавок, если сигнатура не соответствует, или не соответствует кол-во плейсхолдеров, или их вовсе нет - то глядеть в 120 строк вывода об ошибке сомнительное удовольствие. Это сообщение отредактировал(а) boostcoder - 11.4.2011, 16:35 Присоединённый файл ( Кол-во скачиваний: 2 ) simplesocket.zip 3,33 Kb |
||||||||||||
|
|||||||||||||
boostcoder |
|
|||
pattern`щик Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
эм... такой вопрос: а есть ли смысл добавлять методы для синхронных операций?
IMHO - лишнее. |
|||
|
||||
borisbn |
|
||||
Эксперт Профиль Группа: Завсегдатай Сообщений: 4875 Регистрация: 6.2.2010 Где: Ростов-на-Дону Репутация: 22 Всего: 135 |
профайлер не знает, сколько времени уходит непосредственно на отправку/приём, т.к. они асинхронные В Вашем примере ровно столько же new делается на стороне клиента юзера
думаю, что эти new как-то можно соптимизировать. и лучше это сделать в одном месте - в обёртке, а не каждый раз у юзера. А не замахнуться ли нам на Вильяма нашего Собственного Менеджера Памяти думаю, Вы правы. Лишнее. А вот добавить [необязательные] handler'ы connected и disconnected можно -------------------- Женщины отличаются от программистов тем, что у них чары состоят из стрингов |
||||
|
|||||
boostcoder |
|
||||
pattern`щик Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
это да. но я хотел сказать то, что ко всем new не нужно еще и добавлять расходы на копирование.
как, например? пул памяти? ага. а потом кто-то скажет еще добавить аксессоры для ip:port, и что-то еще у обертки есть метод socket() который возвращает ссылку на внутренний сокет. а у него есть все необходимые методы. эта обертка - всего лишь сокет. над ней можно написать другую обертку, к примеру обертку сериализатора/десериализатора для абстрагирования от типа. т.к. сейчас обертка работает только с массивом чаров. Это сообщение отредактировал(а) boostcoder - 11.4.2011, 18:24 |
||||
|
|||||
boostcoder |
|
|||
pattern`щик Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
||||
|
||||
mes |
|
|||
любитель Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
||||
|
||||
boostcoder |
|
|||
pattern`щик Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
mes, спасибо.
я никогда не понимал классику. потому не смотрел. потому не знаю таких высказываний. хотя... Кин-дза-дза мне нравится. помоему это единственное из классики что я могу посмотреть без принуждения.. Это сообщение отредактировал(а) boostcoder - 11.4.2011, 18:44 |
|||
|
||||
boostcoder |
|
|||
pattern`щик Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
mes, кстати. как Вам такой сокет? ;)
|
|||
|
||||
phprus |
|
|||
Шустрый Профиль Группа: Участник Сообщений: 129 Регистрация: 22.8.2006 Репутация: 1 Всего: 3 |
Аллокации, влияют не так сильно, а вот копирование памяти, ее предварительное зануление(если используется std::vector) начинает тормозить уже на скорости обмена с сетью порядка 200Мбит/с (выведено из опыта излишней буферизации в своем приложении), то есть скорость работы приложения ограничивается скоростью копирования памяти. shared_ptr не может принимать массивы, и не во всех случаях безопасен при многопоточности. В первом случае есть shared_array, а второй так просто не решается :( |
|||
|
||||
mes |
|
|||
любитель Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
внимательно не рассматривал, но интуитивно не очень.. |
|||
|
||||
boostcoder |
|
|||
pattern`щик Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
запустите код из этой темы под профайлером. и сами посмотрите на результат. не думаю что профайлер врет. это интересный момент.. |
|||
|
||||
borisbn |
|
|||
Эксперт Профиль Группа: Завсегдатай Сообщений: 4875 Регистрация: 6.2.2010 Где: Ростов-на-Дону Репутация: 22 Всего: 135 |
принимать может ( http://liveworkspace.org/code/93c25ddc57b2...c6880d858a56139 ) удаляет неправильно (без []) -------------------- Женщины отличаются от программистов тем, что у них чары состоят из стрингов |
|||
|
||||
mabrarov |
|
||||
Шустрый Профиль Группа: Участник Сообщений: 100 Регистрация: 12.1.2011 Где: Казань Репутация: 8 Всего: 9 |
Вы просто забыли, что такое шаблон Proactor и как важен для него механизм, предоставляемый Boost.Asio: custom memory allocation (http://www.boost.org/doc/libs/1_46_1/doc/html/boost_asio/overview/core/allocation.html) С этим механизмом (с его применением) Вы сильно удивитесь резвости asio, так как в этом случае все аллокаци во всех используемых очередях (io_service, io_service::strand, deadline_timer) могут свестись к банальному:
|
||||
|
|||||
boostcoder |
|
|||
pattern`щик Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
mabrarov, Марат, здравствуйте ;)
по приведенной вами ссылке, читал, и не раз. не могли бы Вы популярно объяснить, и, желательно с примером. буду сильно благодарен. спасибо. Это сообщение отредактировал(а) boostcoder - 13.4.2011, 02:13 |
|||
|
||||
mabrarov |
|
|||
Шустрый Профиль Группа: Участник Сообщений: 100 Регистрация: 12.1.2011 Где: Казань Репутация: 8 Всего: 9 |
А я думал, что уже достал Вас Объяснить проще, чем в примерах Boost.Asio, я не смогу. К сожалению, проще уже некуда. Могу только пояснить следующее: как любая система построенная по шаблону Proactor (да и вообще - как все многопоточные системы, базирующиеся на очередях - т.е. почти все более-менее "продвинутые" многопоточные системы, например, Intel TBB), asio активно использует очереди (в случае asio - это очереди из функциональных объектов). В связи с этим остро встает вопрос выделения памяти в таких очередях (особенно остро в свете многопоточности и кешей процессора). Intel TBB решает это своим "прокаченным-специализированным" аллокатором (и обещаниями повторно использовать выделяемые блоки). asio использует очень легкое и гибкое решение (и это не единственный случай!): позволяет использовать allocator per async operation (начиная с dev release 1.53 - во всех асинхронных операциях). И вот какая штука: в любом вменяемом (т.е. не "hello world") приложении количество одновременных однотипных асинхронных операций над одним и тем же объектом (например, socket или deadline_timer) всегда ограничено сверху. И зачастую это ограничение равно единице (Вы уже на него нарвались недавно). Исходя из всего вышесказанного, зачастую, Вы можете просто заранее выделить непрерывный блок памяти, который будет удерживаться Вашим handler-ом (например, при помощи shared_ptr). Затем, каждый раз когда asio будет нужна память для чего-то временного (обычно, это память для расположения в очереди - IOCP или boost::asio::io_service::strand или даже deadline_timer), что связанно с асинхронной операцией, для которой Ваш handler является completion handler-ом - asio просто попросит об этом через Ваш же handler. При этом те гарантии что дает asio относительно custom memory allocation, гарантируют, что (при достаточном размере Вашего пред-аллоцированного блока памяти) Вы всегда сможете выделить эту память из того самого, ранее выделенного, блока памяти. Кроме того, гарантии asio позволяют удерживать этот "пред-аллоцированный блок памяти" самим же handler-ом (с небольшим ограничением на handler - см. доки по Boost.Asio 1.53, почти всегда это ограничение выполняется и уж точно всегда его можно легко обойти). Главное, хранить в handler-е не сам блок, а указатель на него (лучше -smart) - чтобы в блок помещался сам handler + что-то временное. В моем проекте (http://sourceforge.net/projects/asio-samples) echo_server (и qt_echo_server, и, вообще, все "asio samples") вообще не выделяет память в куче при своей непосредственной работе (кроме приема новых входящих TCP-соединений, да и тут есть reuse). Custom memory allocation сводит все выделения памяти к тому коду, что я указал - т.е. никаких блокировок и даже никаких атомарных (interlocked) операций. Плюс, в теории (не могу до сих пор проверить) - это должно очень положительно сказаться на использовании CPU-кеша (+ учтите очень правильную реализацию strand-ов в asio). Это сообщение отредактировал(а) mabrarov - 13.4.2011, 02:16 |
|||
|
||||
boostcoder |
|
|||
pattern`щик Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
возможно я не туда смотрю.. вот дока asio-1.4.9 входящая в состав boost-1.46.1: http://www.boost.org/doc/libs/1_46_1/doc/h...allocation.html а вот дока asio-1.5.3 с офф. сайта: http://think-async.com/Asio/asio-1.5.3/doc...allocation.html не вижу разницы. или я не туда смотрю? |
|||
|
||||
mabrarov |
|
||||
Шустрый Профиль Группа: Участник Сообщений: 100 Регистрация: 12.1.2011 Где: Казань Репутация: 8 Всего: 9 |
Вот и я не увидел. Но в release notes к asio-1.5.3 все четко сказано. А уж в коде я сразу "порылся" 8) - ждал этого с самого рождения asio. Не увидел и написал Christopher M. Kohlhoff об этом. Он вежливо поблагодарил за замеченную неточность и... ничего не исправил. |
||||
|
|||||
boostcoder |
|
|||
pattern`щик Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
||||
|
||||
mabrarov |
|
|||
Шустрый Профиль Группа: Участник Сообщений: 100 Регистрация: 12.1.2011 Где: Казань Репутация: 8 Всего: 9 |
К слову, документация у Christopher M. Kohlhoff ну просто очень и очень хорошая (только надо не забывать, что примеры в ней тоже являются обязательным чтивом).
Думаю: 1) когда asio-1.5.3 войдет в Boost C++ Libraries, все будет исправлено; 2) сразу после выхода asio-1.5.3 Chris уже должен был готовиться к BoostCon 2011; 3) судя по тому, что я читал в рассылке asio-users, он действительно занят коммерческими проектами, остается только поражаться тому, как он находит время и силы и вносит столь серьезные (и долгожданные) изменения, как move semantic support и custom memory allocation support for SSL async operations. |
|||
|
||||
boostcoder |
|
|||
pattern`щик Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
||||
|
||||
mabrarov |
|
|||
Шустрый Профиль Группа: Участник Сообщений: 100 Регистрация: 12.1.2011 Где: Казань Репутация: 8 Всего: 9 |
Радует, значит про Asio на просторах СНГ слышали и даже используют. А если чего-то в документации Asio не хватает, то... для этого и существуют asio samples. Дай бог времени и желания - напишу пару статей на русском про наиболее частые ошибки разработчиков, пытающихся использовать Asio вопреки определенным в документации ограничениям/гарантиям. Ну и да, это Open Source (и даже не GPL) - поэтому прежде чем переводить production code на Boost.Asio я внимательно изучал его исходники. Это многое открывает, особенно в плане понимания производительности Asio в сравнении с "raw WinSock". Сравните документацию по Boost.Asio с документацией по ACE или даже с книгами по ACE. |
|||
|
||||
boostcoder |
|
|||
pattern`щик Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
вставьте-ка лучше ссылку в подпись. найти будет легче. и, возможно, гугл проиндексирует.
когда я только начал постигать _network_programming_in_c++_, я пересмотрел несколько библиотек, и ACE одна из них. но от нее я отказался, в виду монструозности. поэтому не юзал. и о качестве документации вряд-ли смогу сказать уверенно. |
|||
|
||||
Правила форума "С++:Общие вопросы" | |
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |