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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> allocator для stl & boost 
:(
    Опции темы
xbarmaglot
Дата 25.3.2016, 17:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Возникла проблема при обработке больших потоков данных. Данные представляют из себя пакеты из сети разного размера.
Профайлер показал, что большое время уходит на выделение памяти и вызов деструкторов стандартных контейнеров.

Хотелось бы выделить большой кусок памяти и не вызывать оператор new при создании объекта, а просто резервировать память.
При удалении объекта хотелось бы тоже не удалять ее, а просто помечать, что она свободна.

Лишь только при нехватке перераспределить новую память.
Существует ли такой глобальный аллокатор для всей библиотеки stl/ищщые?
PM MAIL   Вверх
xvr
Дата 25.3.2016, 18:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



В стандартной stl нет (IMHO). Но никто не мешает написать свой и подсовывать его stl'ным контейнерам
Как то так -
Код

    template<typename _Tp> class allocator
    {
        public:
            typedef size_t     size_type;
            typedef ptrdiff_t  difference_type;
            typedef _Tp*       pointer;
            typedef const _Tp* const_pointer;
            typedef _Tp&       reference;
            typedef const _Tp& const_reference;
            typedef _Tp        value_type;

            template<typename _Tp1>
                struct rebind
                { typedef allocator<_Tp1> other; };

            allocator() throw() { }

            allocator(const allocator&) throw() { }

            template<typename _Tp1>
                allocator(const allocator<_Tp1>&) throw() { }

            ~allocator() throw() { }

            pointer
                address(reference __x) const { return &__x; }

            const_pointer
                address(const_reference __x) const { return &__x; }

            // NB: __n is permitted to be 0.  The C++ standard says nothing
            // about what the return value is when __n == 0.
            pointer
                allocate(size_type __n, const void* = 0)
                { return static_cast<_Tp*>(malloc(__n * sizeof(_Tp))); }

            // __p is not permitted to be a null pointer.
            void
                deallocate(pointer __p, size_type)
                { free(__p); }

            size_type
                max_size() const throw()
                { return size_t(-1) / sizeof(_Tp); }

            // _GLIBCXX_RESOLVE_LIB_DEFECTS
            // 402. wrong new expression in [some_] allocator::construct
            void
                construct(pointer __p, const _Tp& __val)
                { ::new(__p) _Tp(__val); }

#ifdef _MSC_VER
#pragma warning( push )
#pragma warning(disable: 4100)
#endif

            void
                destroy(pointer __p) { __p=__p; __p->_Tp::~_Tp(); }
#ifdef _MSC_VER
#pragma warning( pop )
#endif

    };

    template<typename _Tp>
        inline bool
        operator==(const allocator<_Tp>&, const allocator<_Tp>&)
        { return true; }

    template<typename _Tp>
        inline bool
        operator!=(const allocator<_Tp>&, const allocator<_Tp>&)
        { return false; }



    typedef std::basic_string<char, std::char_traits<char>, allocator<char> > string;

    template<class _Ty>
        class vector : public std::vector<_Ty,allocator<_Ty> > {};

    template<class _Kty, class _Ty>
        class map : public std::map<_Kty, _Ty, std::less<_Kty>, allocator<std::pair<const _Kty, _Ty> > > {};

    template<class _Kty, class _Ty>
        class multimap : public std::multimap<_Kty, _Ty, std::less<_Kty>, allocator<std::pair<const _Kty, _Ty> > > {};

    template<class _Kty>
        class set : public std::set<_Kty, std::less<_Kty>, allocator<_Kty> > {};



malloc/free заменяете на что надо (по вкусу)

PM MAIL   Вверх
baldman88
Дата 25.3.2016, 19:11 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

Репутация: 3
Всего: 7



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


Шустрый
*


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

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



Ну мне приходят пакеты, я их разбираю и далее передаю сам пакет и методанные на обработку и запись.
Поэтому сам пакет приходится хранить (т.е. копировать) и удалять по необходимости.
PM MAIL   Вверх
xbarmaglot
Дата 28.3.2016, 16:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



порылся в интернете - есть готовые быстрые аллокаторы. Например, boost::fast_pool_allocator, TLFS, ...
А можно ли его установить для stl/boost по-умолчанию, или нужно указывать при создании каждого контейнера?
PM MAIL   Вверх
xvr
Дата 28.3.2016, 17:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(xbarmaglot @  28.3.2016,  16:04 Найти цитируемый пост)
А можно ли его установить для stl/boost по-умолчанию,

Нет, но можно сделать свой namespace в котором переопределить (можно просто унаследовать) все stl/boost контейнеры (которые нужны) со своим алокатором

PM MAIL   Вверх
borisbn
Дата 29.3.2016, 16:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

Репутация: 22
Всего: 135



Цитата(baldman88 @  25.3.2016,  19:11 Найти цитируемый пост)
Возможно я неправ, но кажется немного странным то, что при работе с сетью на первое место выходит время на создание и уничтожение контейнеров

Полностью согласен.

xbarmaglot, может у Вас режим Debug? Тогда перейдите в Release и Вы будете приятно удивлены.

Цитата(xbarmaglot @  28.3.2016,  12:51 Найти цитируемый пост)
Поэтому сам пакет приходится хранить (т.е. копировать) и удалять по необходимости. 

Можно ж хранить указатель на пакет в shared_ptr, и вся передача его из контейнера в контейнер будет занимать 4 (или 8) байт на пакет.



--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
xbarmaglot
Дата 29.3.2016, 16:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



не совсем так. Мне приходит большой UDP, который фрагментируется на пакеты.
Само чтение из сокета - это копирование в локальный буфер.
Фрагментация - это второе копирование уже чистого пакета в контейнер.

А далее я уже гоняю умные указатели. Но когда пакет не нужен - удаление его.
Получается, что как минимум один конструктор и один деструктор. Вот они и тупят, как показал профайлер
PM MAIL   Вверх
xbarmaglot
Дата 20.5.2016, 14:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата(xvr @  28.3.2016,  17:07 Найти цитируемый пост)
Нет, но можно сделать свой namespace в котором переопределить (можно просто унаследовать) все stl/boost контейнеры (которые нужны) со своим алокатором

А можно ли как в пространстве std переопределить сам std::allocator?
PM MAIL   Вверх
xvr
Дата 20.5.2016, 15:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(xbarmaglot @  20.5.2016,  14:45 Найти цитируемый пост)
А можно ли как в пространстве std переопределить сам std::allocator? 

Переопределить можно, но компилятор будет ругаться на дубликат определения  smile . Отключить тот, что есть в stl стандартным способом нельзя.
Но можно сделать частичную специализацию allocator для ваших типов (если этого вам хватит)

PM MAIL   Вверх
xbarmaglot
Дата 23.5.2016, 10:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата(xvr @  20.5.2016,  15:44 Найти цитируемый пост)
Но можно сделать частичную специализацию allocator для ваших типов (если этого вам хватит)

У меня достаточно много типов. Сложновато для всех аллокатор свой делать...

Может еще какие варианты есть ?
PM MAIL   Вверх
Alexeis
Дата 23.5.2016, 11:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 12
Всего: 459



Цитата(xbarmaglot @  23.5.2016,  11:37 Найти цитируемый пост)
У меня достаточно много типов. Сложновато для всех аллокатор свой делать...

  Кому сложновато? xvr уже определил вам шаблонные классы для основных контейнеров. Нужно просто пройти рефракторингом по коду и переименовать названия контейнеров. Определять нужно не для каждой переменной, а 1 раз для каждого вида контейнера. В STL едва ли десяток контейнеров наберется и сомневаюсь что у вас используются все.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
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.0571 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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