|
Система, управляемая событиями и SST(super-simple tasker), Выделено из "ООП. Классы и динамические объекты" |
|
|
|
Sep 7 2016, 09:07
|
Профессионал
    
Группа: Свой
Сообщений: 1 047
Регистрация: 2-12-06
Из: Kyiv, Ukraine
Пользователь №: 23 046

|
Недавно я начал пользоваться динамической памятью. Раньше пользовался только статикой, то есть placement new. Со статикой сложно работать с такими шаблонами, как фабрика обьектов, временные задачи итд. Программирую в основном под cortex-m3/m4 Код реализации аллокатора вышел довольно простым и быстрым, критически секции есть, но очень короткие(там прочитать/записать пару байт). При чем я не использую этих всяких монстров под названием RTOS, у меня свой простейший асинхронный планировщик задач, занимает строк 300 кода с комментариями(погуглите запрос "super simple tasker", поймете что это). В купе с динамическим аллокатором, variable element-size queue, новыми фишками C++ (шаблоны, лямбда-функции, auto) получается очень простой, безопасный и мощный фреймворк. Вспоминаю работу с классическими Thread-ами(с ихними стеками - куча кода было написано для анализа программ на предмет нужного обьема стека, и теперь эта куча кода отправлена на мусорку) со всеми этими тяжеленными мютексами, семафорами, вечными циклами как страшный сон.
Если кому интересно - расскажу и покажу как это все работает.
|
|
|
|
|
 |
Ответов
|
Sep 9 2016, 06:12
|
Профессионал
    
Группа: Свой
Сообщений: 1 047
Регистрация: 2-12-06
Из: Kyiv, Ukraine
Пользователь №: 23 046

|
Цитата Хотя интересно было узнать то, что помимо стандартных new/delete, существуют и свои средства (стратегии) для управления кучами. dew/delete никуда не деваются, но мы их можем перегружать и иметь свою реализацию. Потом есть всякие smart-pointerы и reference count-ы - это для того, чтобы голова за delete не болела. Но их надо использовать с осторожностью(равно как и delete) Динамическая память напрямую связана с той средой, в которой работаете. В многопоточной среде динамическая память приводит к большим тормозам и проблемам - поскольку на время работы аллокатора надо блочить все потоки и планировщик, а возможно и часть прерываний. В то время как в SST-модели в этом нет необходимости, блочится только часть системы, а не практически вся. Цитата Может быть выложите реализацию делегатов? Сам использую свой велосипед и собираю велосипеды других с целью повышения образования. Выложу ниже. Велосипеды/не велосипеды, но эта реализация отлично работает многие годы. А сделал я ее потому что когда я попытался применить нормальный std::function на Atmega8, то это сразу сожрало всю оператирку(и все рано ее не хватило), потянуло за собой кучу ненужного мусора. В итоге сделал этот велосипед na 80 строк(вместо нескольких тысяч в std) за час. Держите статическую версию, в большинстве случаев ее достаточно. А на слабых МК (до 8-16кб оперативки) только она и уместна CODE template<class T, int d_size=1> class delegate;
template<class TRet, class... TArgs, int d_size> class delegate<TRet(TArgs...),d_size> { public: delegate(){}
// copy constructor and copy operator= template<int size_another> delegate(const delegate<TRet(TArgs...),size_another>& another){ operator=(another); }
template<int size_another> delegate& operator=(const delegate<TRet(TArgs...),size_another>& another){ static_assert(sizeof(another) <= sizeof(*this), "RHS too large"); wrapper_ = another._private_get_wrapper(); for(unsigned i=0; i<sizeof(another._private_get_data()) / sizeof(data_.vp[0]); i++){ data_.vp[i] = another._private_get_data().vp[i]; } return *this; }
// lambda, static function and function object template<class TLambda> delegate(const TLambda& lambda){ setFunction(lambda); }
template<class TLambda> delegate& operator=(const TLambda& lambda){ return setFunction(lambda); }
// For lambda, static function and function object template<class TLambda> delegate& setFunction(const TLambda& lambda){ struct Wrapper{ Wrapper(const TLambda& lambda) : la(lambda) {}
static TRet wrapper(void* data, TArgs ... args){ Wrapper *w = static_cast<Wrapper*>(data); return w->la(args...); }
void* operator new(size_t, void *place){ return place; } TLambda la; }; static_assert(sizeof(Wrapper) <= sizeof(data_), "Wrapper too large");
new(&data_) Wrapper(lambda); wrapper_ = &Wrapper::wrapper; return *this; }
// invoke wrapper TRet operator()(TArgs ... args){ return wrapper_(&data_, args...); }
TRet operator()(TArgs ... args)const{ return wrapper_(const_cast<t_data*>(&data_), args...); }
private: typedef TRet (*t_wrapper)(void*, TArgs...);
t_wrapper wrapper_; union t_data{ void *vp[d_size]; } data_;
// really private public: const t_wrapper& _private_get_wrapper()const{ return wrapper_; } const t_data& _private_get_data()const{ return data_; } }; Несмотря на такое изобилие кода(который делается 1 раз) на самом деле для выполнения делегата компилятор генерирует 2 инструкции(на кортексе) - чтение указателя wrapper и прыжок на него  А тело самой функции-делегата встраивает в wrapper, фактического вызова функции внутри wrappera нет. Создание делегата тоже очень простая операция - запись указателя(одна инструкция) и запись данных(обычно тоже одна инструкция, в зависимости от обьема данных - сколько слов, столько и инструкций или одна STM для всех)
|
|
|
|
|
Sep 9 2016, 07:47
|
Профессионал
    
Группа: Свой
Сообщений: 1 047
Регистрация: 2-12-06
Из: Kyiv, Ukraine
Пользователь №: 23 046

|
Цитата Очень бы хотелось увидеть как бы вы обслуживали много клиентов, рисовали GUI и делали еще то что нужно и именно на голой системе и именно со своим SST и чтоб в масштабах ВСЕЙ системы был бы один стек и один поток. Собственно это то, с чего мы начинали нашу дискуссию. Так я именно это и постоянно делаю! У меня GUI, сложные вычисления, куча IO(флешки,ацп,датчики 1wire) отлично работают на SST без единых тормозов и проблем. На многопоточной оси аля FreeRTOS постоянно были проблемы, то гонки, то оверхед большой, то еще что-то. Цитата И для того чтобы организовать то-же самое вам придется реализовать примерно такие-же механизмы в своей системе. Ну так они реализованы - это SST  При чем довольно просто, сам SST - это около 300 строк кода, динамическая очередь - почти 200 строк кода, очередь задач - 60 строк кода, делегат(Вы уже его видели выше) - 80 строк кода Цитата Правильно уже вам тут говорили, вы даже реализацию TCP/IP со своим SST запаритесь делать. Сделана и отлично работает. Цитата Начали мы с SST где один стек и один поток на всех в системе давайте и будем продолжать в том-же духе. Ну так я показал, как на своем SST я работаю с DataFlash - привел полный код операции ее стирания. Что там непонятного? Могу любую другую задачу показать как я делаю ее на SST. Говорите какую - приведу код, тк у меня практически все задачи уже решены в виде простейших библиотек и я их использую когда надо - строю программу из этих кубиков. Цитата(Serhiy_UA @ Sep 9 2016, 10:23)  В моем случае под 7 версией FreeBCD на индустриальном компьютере в режиме реального времени одновременно работают пять равно приоритетных программ. Каждая через new/delete (без перегрузок) создает для себя динамические объекты в куче. Если куча общая, то ОС должна четко организовывать управление кучей для всех программ. Хотел узнать (прочесть) об этом немного больше, хотя и так кое-что уже прояснилось. Ну в таких сложных ОС, как FreeBSD управление кучей очень сложное. Куча для каждого процесса своя, а для потоков внутри этого процесса общая, и ессно ядру нужно ею управлять так, чтобы это не сказывалось на других процессах, там все довольно сложно и вникать туда смысла нет - жизни не хватит. Зато есть смысл делать динамику на embedded, где и памяти мало, и других ресурсов, но чувствовать себя там практически так, как будто под PC пишешь. В FreeBSD там все довольно грамотно да и работать в асинхронном стиле(без ожиданий и циклов) там гораздо проще, чем в линуксе. В линуксе до сих пор нет нормальных асинхронных IO, есть костыли вроде epoll. Тогда как в FreeBSD есть Kqueue. Думаю, если мой тест запустить на FreeBSD, то NodeJS еще сильнее убьет в хлам классические pthread. А тем временем провел другой тест - сервер выдает не файл(который ОС выдает из кеша, а не читает по факту с диска) а рандомные данные по таймеру по 100 байт каждые 10 милисекунд вечно, пока клиент не отключится. Вот так это выглядит на NodeJS, в однопоточном асинхронном стиле: Код var timer; function on_socket_closed(){ n_connections--; clearInterval(timer); }
// Periodically send random data to client timer = setInterval(function(){ var str; for(var i=0; i<100; i++){ str+= String.fromCharCode(Math.random()*256); } socket.write(str); }, 10); То есть для каждого клиента мы создаем таймер, в обработчике события которого генерируется рандом и потом ставится в очередь на отправку клиенту. Не шибко эффективный способ,тк время генерации рандома велико - тк это мы делаем синхронным блокирующим способом - в цикле for. правильно было бы прoчитать эти данные из готового асинхронного рандом-генератора (типа /dev/urandom) и передать клиенту - моментально, одной строчкой. Но тк я буду делать то же самое на С, только в многопоточном стиле - специально сделал так, чтобы сразу не убить в хлам многопоточную модель  И того такой сервер на моем ноуте может обслуживать 3900 клиентов одновременно и занимает при этом 80МБ оперативки. При чем клиент запущен на том же ноуте, асинхронный тот же, что и прежний, на JS. Сейчас наклепаю на C в мнгопоточном блокирующем стиле.
|
|
|
|
Сообщений в этой теме
brag Система, управляемая событиями и SST(super-simple tasker) Sep 7 2016, 09:07 sigmaN Ну так извините меня, классические, как вы говорит... Sep 7 2016, 10:07 Serhiy_UA Цитата(brag @ Sep 7 2016, 12:07) Не очень... Sep 7 2016, 10:24 brag ЦитатаНапример если у вас хотя-бы одна из задач бу... Sep 7 2016, 11:56 Serhiy_UA brag, Спасибо за пояснения! Sep 7 2016, 12:16 arhiv6 Цитата(brag)Если кому интересно - расскажу и покаж... Sep 7 2016, 12:18 AHTOXA Цитата(brag @ Sep 7 2016, 14:07) Если ком... Sep 7 2016, 12:17 Kabdim Цитата(brag @ Sep 7 2016, 12:07) Если ком... Sep 7 2016, 12:36 brag ЦитатаПрисоединюсь к интересующимся. Если я правил... Sep 7 2016, 12:47 AlexandrY Цитата(brag @ Sep 7 2016, 15:47) Я конечн... Sep 7 2016, 13:48 brag ЦитатаВытесняющая асинхронная многозадачность сейч... Sep 7 2016, 13:57 sigmaN Очень интересно. Видимо этот SST прошел мимо меня.... Sep 7 2016, 15:50 brag Все, что мы теряем отказываясь от классических тре... Sep 7 2016, 16:20 DASM Что то не пойму, речь о кооперативной "оси... Sep 7 2016, 16:43 sigmaN Никто же не мешает организовать обмен ивентами и в... Sep 7 2016, 17:04 brag ЦитатаЧто то не пойму, речь о кооперативной ... Sep 7 2016, 17:14 sigmaN Наврено правильно сравнивать реализацию вещей обес... Sep 7 2016, 18:37 arhiv6 Цитата(DASM)Что то не пойму, речь о кооперативной ... Sep 7 2016, 19:01 DASM Спасибо, интересно, почитал. Sep 7 2016, 19:37 brag ЦитатаВ то время как в классической модели я могу ... Sep 7 2016, 20:04 DASM Ну я бы не стал столь восторженно писать, не могут... Sep 7 2016, 20:43 brag Цитата(DASM @ Sep 7 2016, 23:43) Ну я бы ... Sep 7 2016, 21:32 sigmaN ЦитатаДа и PC мир уже давно переходит на event-ы..... Sep 8 2016, 00:18 DASM а что такое "императивный код"? https://... Sep 8 2016, 00:52 arhiv6 Императивное программирование Sep 8 2016, 02:23 DASM "В этом случае программа представляет собой ф... Sep 8 2016, 02:37 ViKo Допустим, надо стереть flash-память, что длится д... Sep 8 2016, 04:35 sigmaN Ну почему же обязательно создавать задачу. Стирани... Sep 8 2016, 07:03 ViKo Ветвление, это что? После стирания нужно дальше р... Sep 8 2016, 07:17 brag ЦитатаНу давайте не будем путать всё в кучу. Это р... Sep 8 2016, 07:27 sigmaN ЦитатаНет, физически там один поток и один стек. Х... Sep 8 2016, 07:31 brag Цитата(sigmaN @ Sep 8 2016, 10:31) Хотело... Sep 8 2016, 07:38 ViKo Слезть с шины, и что делать? Висеть в задаче без ... Sep 8 2016, 07:39 brag Цитата(ViKo @ Sep 8 2016, 10:39) Слезть с... Sep 8 2016, 08:16 501-q Приветствую!
Модель SST хорошо работает до то... Sep 8 2016, 07:55 sigmaN ЦитатаКонечо. При чем написанного на языке Javascr... Sep 8 2016, 08:19 brag ЦитатаПриветствую!
Модель SST хорошо работает... Sep 8 2016, 08:25 sigmaN Прям с удовольствием потестирую )))))
Особенно со... Sep 8 2016, 08:33 DASM На самом деле мы наверное действительно отстали от... Sep 8 2016, 08:37 brag ЦитатаВсе же Javascript для эмбеддед старого добро... Sep 8 2016, 08:45 arhiv6 brag, на сколько я понял, в обычном SST пока задач... Sep 8 2016, 08:47 brag ЦитатаНу как бы с идеей SST крутится всякая мелкая... Sep 8 2016, 08:48 sigmaN Ладно бы товарищ просто говорил что ребят, так про... Sep 8 2016, 08:54 AHTOXA Цитата(sigmaN @ Sep 8 2016, 13:54) Но у н... Sep 8 2016, 09:04 brag Цитатаbrag, на сколько я понял, в обычном SST пока... Sep 8 2016, 09:11 sigmaN ЦитатаПоэтому и в сях сейчас развивают асинхронное... Sep 8 2016, 09:16 brag ЦитатаЭто когда куча сокетов в массиве а потом в ц... Sep 8 2016, 09:22 sigmaN ЦитатаВы все равно ничего не поняли. Ключевое слов... Sep 8 2016, 09:33 brag Цитата(sigmaN @ Sep 8 2016, 12:33) Могу в... Sep 8 2016, 09:45  DASM Цитата(brag @ Sep 8 2016, 12:45) Для безо... Sep 8 2016, 09:49   brag Цитата(DASM @ Sep 8 2016, 12:49) В случае... Sep 8 2016, 09:58 DASM а не в безопастности ли выполнения коренное различ... Sep 8 2016, 09:39 sigmaN ЦитатаWaitForMultipleObjects блокирует пользовател... Sep 8 2016, 09:53 sigmaN ЦитатаХотя даже с гиговым файлом/файлами однопоточ... Sep 8 2016, 09:58 brag ЦитатаНу во-первых там есть таймаут. Так что поток... Sep 8 2016, 10:13 arhiv6 brag, спасибо за ответ. Но всё-равно не всё понятн... Sep 8 2016, 10:14 brag arhiv6 , Вы путаете задачу и обработчик события. Э... Sep 8 2016, 10:26 arhiv6 brag, спасибо большое за разъяснение, теперь всё п... Sep 8 2016, 10:52  brag Цитата(arhiv6 @ Sep 8 2016, 13:52) [/b]br... Sep 8 2016, 10:57 sigmaN ЦитатаНу как оно физически, да еще и под виндой я ... Sep 8 2016, 10:34 brag ЦитатаВот тут то мы и начинаем докапываться до сут... Sep 8 2016, 10:47 sigmaN Лаадно, тогда вы проводите правильный тест, выклад... Sep 8 2016, 11:34 brag Еще огромное преимущество SST-модели в том, что та... Sep 8 2016, 11:40 AlexandrY Цитата(brag @ Sep 8 2016, 14:40) Ок, дела... Sep 8 2016, 12:39 sigmaN Вы видимо думаете, что мы тут все совсем темные, д... Sep 8 2016, 12:34 brag ЦитатаВ MQX есть в том числе и ваша гениальная иде... Sep 8 2016, 12:42 AlexandrY Цитата(brag @ Sep 8 2016, 15:42) SST - эт... Sep 8 2016, 13:03  brag Цитата(AlexandrY @ Sep 8 2016, 16:03) SST... Sep 8 2016, 15:18 Kabdim А топик так хорошо начинался. Тоже что ли залезт... Sep 8 2016, 12:51 brag Хух, сишный клиент осилил. То segfault схлопнешь, ... Sep 8 2016, 17:22 psL Цитата(brag @ Sep 8 2016, 20:22) 1000 пот... Sep 9 2016, 20:59 sigmaN Интересный способ проверить сколько потоков может ... Sep 8 2016, 17:44 brag ЦитатаА мы уверены, что все клиенты параллельно ка... Sep 8 2016, 19:21 Herz Поступило предложение тему разделить и основное об... Sep 8 2016, 19:38 AHTOXA Цитата(Herz @ Sep 9 2016, 00:38) Поступил... Sep 8 2016, 21:03 Serhiy_UA Цитата(Herz @ Sep 8 2016, 22:38) Поступил... Sep 9 2016, 04:53 brag Возражений нет, но я не автор. Про аллокатор у мен... Sep 8 2016, 20:04 sigmaN Как весело мы ушли в сторону от обсуждения планиро... Sep 8 2016, 20:43 brag NodeJS свободно может работать без ОС и потоков во... Sep 8 2016, 21:10 shreck 2brag
В приведенном вами коде проскакивает
Кодdel... Sep 9 2016, 02:16 sigmaN Очень бы хотелось увидеть как бы вы обслуживали мн... Sep 9 2016, 07:36 sigmaN Всё всё, хватит, мы уже поняли что на Node.js можн... Sep 9 2016, 07:52 alexunder Цитата(sigmaN @ Sep 9 2016, 09:52) Всё вс... Sep 9 2016, 07:57  brag Цитата(alexunder @ Sep 9 2016, 10:57) Вер... Sep 9 2016, 08:00   alexunder Цитата(brag @ Sep 9 2016, 10:00) Естестве... Sep 9 2016, 08:16 brag Так я уже показал, как я работаю с Датафлеш. Приве... Sep 9 2016, 07:57 brag Сделал сервер сишный блокирующий многопоточний. Ка... Sep 9 2016, 08:26 Сергей Борщ Почерпнул много интересного из этого обсуждения. П... Sep 9 2016, 09:36 brag Сергей Борщ, это называется Partial Template Speci... Sep 9 2016, 09:58 sigmaN Да, я тоже могу сказать, что узнал что-то новое из... Sep 9 2016, 10:42 brag ЦитатаДля начала давайте определимся, что любой об... Sep 9 2016, 11:55 sigmaN Кстати справедливости ради надо добавить, что идея... Sep 9 2016, 19:24 brag Smalltalk прикольная штука, но не прижилась. Но та... Sep 9 2016, 20:04 sigmaN Цитатавсе - вы программируете асинхронно, пора вык... Sep 9 2016, 20:21 brag Ок, с фанатичностью убавим
Мне тоже лень было, но... Sep 9 2016, 20:51 sigmaN ЦитатаВидимо гуру не знает, что "Сервак на No... Sep 9 2016, 22:16 brag ЦитатаКаждый поток в линукс создается со стеком ~8... Sep 10 2016, 05:21
3 страниц
1 2 3 >
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|