crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

> Создание быстродействующего распределителя памяти, для std::vector или замена глобальных операций выделения памяти
AD
  опции профиля:
сообщение 29.6.2009, 10:38
Сообщение #1


Профессионал
*****

Группа: Участник
Сообщений: 2003
Регистрация: 4.2.2008
Из: S-Petersburg
Пользователь №: 84

Спасибо сказали: 70 раз(а)




Репутация:   17  


Раньше был обычный массив (динамический), который содержал значения определенных параметров, прочитанных из лог-файла (широта, долгота, скорость и пр.). Сейчас сделал в виде вектора. Вместо оператора new теперь использую resize. Но так как эти операции чересчур затратные (а цикл может содержать и 100000 итераций (где каждый раз происходит выделение)), то стало необходимо сделать алгоритм немного по-другому.
Выделять память блоками. Т.е. вместо след. операций:
code1
t.params = new PARAMVALUE[rec_descr.size()];
t.words = new uint[rec_descr.size()];
memset(t.params, 0, sizeof(PARAMVALUE) * rec_descr.size());
memset(t.words, 0, sizeof(uint) * rec_descr.size());

Делать следующее:
code2
/// 0 <= num_block <= 1000
char *buff, *buff1;
if(num_block > 1000)
{
buff = new char[rec_descr.size() * BLOCKSIZE];
buff1 = new char[rec_descr.size() * BLOCKSIZE];
flag = false;
num_block = 0;
}
++num_block;
t.params = buff + rec_descr.size() * num_block;
t.words = buff1 + rec_descr.size() * num_block;


При замене на QVector code1 перешел в следующий:
code3
t.params.resize(rec_descr.size());
t.words.resize(rec_descr.size());


Как переписать code2 для использования в векторе QVector? Заранее благодарен за помощь....

Сообщение отредактировал AD - 30.6.2009, 15:08
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
 
Начать новую тему
Ответов
Tonal
  опции профиля:
сообщение 30.6.2009, 10:54
Сообщение #2


Активный участник
***

Группа: Участник
Сообщений: 452
Регистрация: 6.12.2007
Из: Новосибирск
Пользователь №: 34

Спасибо сказали: 69 раз(а)




Репутация:   17  


Можешь написать свой, проще зацепить из буста. :)
Где-то я встречал библиотечку шаблонов для лёгкого написания аллокаторов stl - думал в бусте, сейчас не вспомню...
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AD
  опции профиля:
сообщение 30.6.2009, 11:11
Сообщение #3


Профессионал
*****

Группа: Участник
Сообщений: 2003
Регистрация: 4.2.2008
Из: S-Petersburg
Пользователь №: 84

Спасибо сказали: 70 раз(а)




Репутация:   17  


Цитата(Tonal @ 30.6.2009, 11:54) *
Можешь написать свой, проще зацепить из буста. :)
Где-то я встречал библиотечку шаблонов для лёгкого написания аллокаторов stl - думал в бусте, сейчас не вспомню...

Думаю, тогда может попробовать написать свой! :) Если что, поможете? Надо научиться их писать! Заодно увидеть, как это все устроено. А то одной теории из Саттера, маловато будет!
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AD
  опции профиля:
сообщение 30.6.2009, 12:09
Сообщение #4


Профессионал
*****

Группа: Участник
Сообщений: 2003
Регистрация: 4.2.2008
Из: S-Petersburg
Пользователь №: 84

Спасибо сказали: 70 раз(а)




Репутация:   17  


да, кстати, а мне нужно наследоваться от стандартного аллокатора? Или полностью "свои велосипеды" писать?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AD
  опции профиля:
сообщение 30.6.2009, 14:09
Сообщение #5


Профессионал
*****

Группа: Участник
Сообщений: 2003
Регистрация: 4.2.2008
Из: S-Petersburg
Пользователь №: 84

Спасибо сказали: 70 раз(а)




Репутация:   17  


Странно, как-то не очень помогло. Или я что-то забыл?
allocator
#ifndef SPECIFIC_ALLOCATOR_INL
#define SPECIFIC_ALLOCATOR_INL

#include <memory>
#include <cassert>

/// Собственный распределитель памяти
template <typename T> void allocator_construct(T* p, const T& t) { new(p) T(t); }
template <typename T> void allocator_destroy(T* p) { p -> ~T(); }

template <typename T, typename A>
struct rebind_allocator
{
    typedef typename A::template rebind<T> binder;
    typedef typename binder::other type;
};

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

   template <typename Other>
   struct rebind
   { typedef spec_allocator<Other> other; };

   spec_allocator() {}
   template <typename Other> spec_allocator(const spec_allocator<Other>&) {}
   spec_allocator(const spec_allocator&) {}
   template <typename Other> spec_allocator& operator=(const spec_allocator<Other>&) { return *this; }
   ~spec_allocator() {}
   pointer address(reference x) { return &x; }
   const_pointer address(const_reference x) const { return &x; }
   pointer allocate(size_type n, const void* = 0)
   { return (n != 0) ? reinterpret_cast<pointer>(::operator new(n * sizeof(value_type))) : 0; }
   void deallocate(pointer p, size_type n)
   {
       assert((p == 0) == (n == 0));
       ::operator delete((void*)p);
   }
   size_type max_size() const { return size_t(-1) / sizeof(value_type); }
   void construct(pointer p, const T& val) const { allocator_construct(p, val); }
   void destroy(pointer p) const { allocator_destroy(p); }
};

#endif // SPECIFIC_ALLOCATOR_INL


Вот как использую
/// Структура для хранения всех значений параметров в логе
struct LOGRECORD
{
public:
    //PARAMVALUE* params;                    ///< массив параметров
    std::vector<PARAMVALUE, spec_allocator<PARAMVALUE> > params;    ///< вектор параметров
/// ....
};

В чем еще могут быть проблемы? Что-то еще следует дописать?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Tonal
  опции профиля:
сообщение 1.7.2009, 8:47
Сообщение #6


Активный участник
***

Группа: Участник
Сообщений: 452
Регистрация: 6.12.2007
Из: Новосибирск
Пользователь №: 34

Спасибо сказали: 69 раз(а)




Репутация:   17  


Цитата(AD @ 30.6.2009, 18:09) *
Странно, как-то не очень помогло. Или я что-то забыл?
...
В чем еще могут быть проблемы? Что-то еще следует дописать?

Ты выделяешь столько памяти, сколько просит клиент (std::vector). Ровно это же и делает стандартный аллокатор. Т.е. ты ничего не выигрываешь.
Для того, чтобы получить эффект, нужно изменить стратегии выделения - например выделять память сразу большими блоками, а потом раздавать на них место. :)
Попробуй таки зацепить аллокатор из буста - хоть посмотришь к чему надо стремиться. :)

Да, можно ещё такой финт провернуть:
При разборе блока параметры загоняешь в список - std::list с быстрым аллокатором.
Когда блок разобран, создаёшь массив std::vector или обычный массив с уже известным размером и копируешь туда данные.
Если все блоки не очень большого размера, то можно выделить для аллокатора списка сразу память под самый большой блок и переразмещений в нём не будет.
И массивы будут размещаться всего один раз.
Стало быть получим количество выделений памяти в идеале: кол-во блоков + 1. :)
А переразмещений не будет вовсе - что сильно снизает нагрузку на всю подсистему памяти. :)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AD
  опции профиля:
сообщение 1.7.2009, 9:05
Сообщение #7


Профессионал
*****

Группа: Участник
Сообщений: 2003
Регистрация: 4.2.2008
Из: S-Petersburg
Пользователь №: 84

Спасибо сказали: 70 раз(а)




Репутация:   17  


Цитата(Tonal @ 1.7.2009, 9:47) *
Ты выделяешь столько памяти, сколько просит клиент (std::vector). Ровно это же и делает стандартный аллокатор. Т.е. ты ничего не выигрываешь.
Для того, чтобы получить эффект, нужно изменить стратегии выделения - например выделять память сразу большими блоками, а потом раздавать на них место. :)
Попробуй таки зацепить аллокатор из буста - хоть посмотришь к чему надо стремиться. :)

Я аллокатор из буста и смотрел. Вот именно большими блоками и хочу выделять. Можешь на коде показать, как это провернуть? Я не очень понимаю...

Цитата(Tonal @ 1.7.2009, 9:47) *
Да, можно ещё такой финт провернуть:
При разборе блока параметры загоняешь в список - std::list с быстрым аллокатором.
Когда блок разобран, создаёшь массив std::vector или обычный массив с уже известным размером и копируешь туда данные.
Если все блоки не очень большого размера, то можно выделить для аллокатора списка сразу память под самый большой блок и переразмещений в нём не будет.
И массивы будут размещаться всего один раз.
Стало быть получим количество выделений памяти в идеале: кол-во блоков + 1. :)
А переразмещений не будет вовсе - что сильно снизает нагрузку на всю подсистему памяти. :)

Спасибо большое. Мне бы хоть пример небольшой, тогда смогу сделать, а так сложно представить, как это реализовать!
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Tonal
  опции профиля:
сообщение 1.7.2009, 10:44
Сообщение #8


Активный участник
***

Группа: Участник
Сообщений: 452
Регистрация: 6.12.2007
Из: Новосибирск
Пользователь №: 34

Спасибо сказали: 69 раз(а)




Репутация:   17  


Цитата(AD @ 1.7.2009, 13:05) *
Цитата(Tonal @ 1.7.2009, 9:47) *
Попробуй таки зацепить аллокатор из буста - хоть посмотришь к чему надо стремиться. :)

Я аллокатор из буста и смотрел. Вот именно большими блоками и хочу выделять. Можешь на коде показать, как это провернуть? Я не очень понимаю...

Вот и смотри как там работают с памятью.
А подключить действительно просто - бостовский пул не требует подключения библиотек - только хедеров и пути к ним. :)

Кстати, в том коде, который ты приводил в сообщении 13
Попробуй сделать для LOGRECORD конструктор с размером параметров:
explicit LOGRECORD::LOGRECORD(size_t size) : params(size) ...

Конструирование вектора сразу нужного размера выгоднее, чем конструирование пустого, с последующим его увеличением.

П.С.
Цитата(AD @ 1.7.2009, 13:05) *
Цитата(Tonal @ 1.7.2009, 9:47) *
Да, можно ещё такой финт провернуть...

Спасибо большое. Мне бы хоть пример небольшой, тогда смогу сделать, а так сложно представить, как это реализовать!

Рассмотрел ещё раз твой код и подумал, что я похоже фигню написал.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AD
  опции профиля:
сообщение 1.7.2009, 10:50
Сообщение #9


Профессионал
*****

Группа: Участник
Сообщений: 2003
Регистрация: 4.2.2008
Из: S-Petersburg
Пользователь №: 84

Спасибо сказали: 70 раз(а)




Репутация:   17  


Цитата(Tonal @ 1.7.2009, 11:44) *
Вот и смотри как там работают с памятью.
А подключить действительно просто - бостовский пул не требует подключения библиотек - только хедеров и пути к ним. :)

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

Цитата(Tonal @ 1.7.2009, 11:44) *
Кстати, в том коде, который ты приводил в сообщении 13
Попробуй сделать для LOGRECORD конструктор с размером параметров:
explicit LOGRECORD::LOGRECORD(size_t size) : params(size) ...

Конструирование вектора сразу нужного размера выгоднее, чем конструирование пустого, с последующим его увеличением.

Это я уже сделал! :)


Цитата(Tonal @ 1.7.2009, 11:44) *
П.С. Рассмотрел ещё раз твой код и подумал, что я похоже фигню написал.

В чем именно? :blink:
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Сообщений в этой теме
- AD   Создание быстродействующего распределителя памяти   29.6.2009, 10:38
- - Tonal   Интересно, в code2 при num_block <= 1000 t.para...   29.6.2009, 10:53
|- - AD   Цитата(Tonal)Интересно, в code2 при num_block ...   29.6.2009, 11:10
- - Litkevich Yuriy   Цитата(AD @ 29.6.2009, 14:38) Выделять па...   29.6.2009, 11:36
|- - AD   Цитата(Litkevich Yuriy @ 29.6.2009, 12:36...   29.6.2009, 11:59
|- - AD   Очень прошу помочь. Как реализовать код для QVecto...   29.6.2009, 13:25
- - SABROG   Кстати интересный класс есть QVarLengthArray, если...   29.6.2009, 11:43
- - Litkevich Yuriy   Цитата(AD @ 29.6.2009, 17:25) Делать выде...   29.6.2009, 13:34
|- - AD   Цитата(Litkevich Yuriy @ 29.6.2009, 14:34...   29.6.2009, 14:05
- - Litkevich Yuriy   по ссылке, что я привёл, дочитай до конца. Там ест...   29.6.2009, 15:19
|- - AD   Юра, мне непонятна одна конкретная вещь: вот я в...   29.6.2009, 16:14
- - Litkevich Yuriy   Цитата(AD @ 29.6.2009, 20:14) Как теперь ...   29.6.2009, 17:52
|- - AD   Цитата(Litkevich Yuriy @ 29.6.2009, 18:52...   29.6.2009, 18:02
|- - BRE   AD, прости, а можешь словами рассказать, что нужно...   29.6.2009, 19:18
|- - AD   code 1, code2 из первого примера - это рабочие ко...   29.6.2009, 22:01
- - Tonal   Т.е. у тебя много маленьких векторочков. В stl у ...   30.6.2009, 7:15
|- - AD   Цитата(Tonal)Т.е. у тебя много маленьких векторочк...   30.6.2009, 8:23
|- - Tonal   Цитата(AD @ 30.6.2009, 12:23) Цитата(Tona...   30.6.2009, 10:28
|- - AD   Цитата(Tonal @ 30.6.2009, 11:28) Ничего п...   30.6.2009, 10:41
- - BRE   Как я понял задачу. Есть несколько конфигурационны...   30.6.2009, 8:45
|- - AD   Цитата(BRE @ 30.6.2009, 9:45) Как я понял...   30.6.2009, 9:03
|- - BRE   Цитата(AD @ 30.6.2009, 10:03) Есть ини-фа...   30.6.2009, 9:28
|- - AD   Цитата(BRE @ 30.6.2009, 10:28) Так может ...   30.6.2009, 9:31
- - SABROG   Цитата(Tonal @ 30.6.2009, 8:15) и сделать...   30.6.2009, 8:53
- - Tonal   Можешь написать свой, проще зацепить из буста. Гд...   30.6.2009, 10:54
|- - AD   Цитата(Tonal @ 30.6.2009, 11:54) Можешь н...   30.6.2009, 11:11
|- - AD   да, кстати, а мне нужно наследоваться от стандартн...   30.6.2009, 12:09
|- - AD   Странно, как-то не очень помогло. Или я что-то заб...   30.6.2009, 14:09
|- - BRE   Цитата(AD @ 30.6.2009, 15:09) В чем еще м...   30.6.2009, 14:56
|- - Tonal   Цитата(AD @ 30.6.2009, 18:09) Странно, ка...   1.7.2009, 8:47
|- - AD   Цитата(Tonal @ 1.7.2009, 9:47) Ты выделяе...   1.7.2009, 9:05
|- - AD   В boost в файле allocator.hpp нашел следующий код:...   1.7.2009, 9:59
|- - Tonal   Цитата(AD @ 1.7.2009, 13:05) Цитата(Tonal...   1.7.2009, 10:44
|- - AD   Цитата(Tonal @ 1.7.2009, 11:44) Вот и смо...   1.7.2009, 10:50
||- - AD   Вот блин. Сделал следующий распределитель: allocat...   1.7.2009, 14:55
|- - AD   Цитата(Tonal @ 1.7.2009, 11:44) Вот и смо...   13.7.2009, 11:40
- - Влад   Хм, есть опасение, что если причиной разработки ал...   30.6.2009, 14:49
|- - AD   Влад, исходя из твоих слов, следует заменить глоба...   30.6.2009, 14:59
- - BRE   Почитай вот эту тему. В конце есть готовый алокато...   1.7.2009, 10:37
- - BRE   А ты в профилировщике результаты смотрел, точно им...   1.7.2009, 15:24
|- - AD   Цитата(BRE @ 1.7.2009, 16:24) А ты в проф...   1.7.2009, 15:57
- - Влад   Цитата(AD @ 30.6.2009, 15:59) Влад, исход...   1.7.2009, 16:07
|- - AD   Цитата(Влад @ 1.7.2009, 17:07) Нет. Тут ф...   1.7.2009, 16:10
|- - BRE   Цитата(AD @ 1.7.2009, 17:10) Да, видимо, ...   1.7.2009, 16:49
|- - AD   У меня видоизменилась несколько структура, потому ...   1.7.2009, 17:14
|- - AD   Заметил такую странную вещь: Указал CHUNK_SIZE = 2...   1.7.2009, 17:57
- - Tonal   Может всё же так: ... struct Chunk { Chunk* ne...   2.7.2009, 8:04
|- - AD   Цитата(Tonal @ 2.7.2009, 9:04) Да, ты вед...   2.7.2009, 9:11
|- - AD   Так.... совсем интересно. При загрузке большого ко...   2.7.2009, 10:51
- - Влад   Видел: http://rsdn.ru/forum/cpp.applied/930448.asp...   2.7.2009, 13:38
|- - AD   Так, получилось ускорение с помощью массивов (пока...   3.7.2009, 12:00
|- - AD   Сделал распределитель памяти следующий: allocator#...   6.7.2009, 17:36
|- - AD   Буду очень благодарен за любую помощь. Очень требу...   7.7.2009, 11:07
|- - AD   Так... Ну теперь я совсем не понимаю, почему при з...   8.7.2009, 12:12
|- - AD   Сделал так: вначале чтение всех файлов. Пихаем про...   9.7.2009, 17:10
- - Влад   Цитатаbcp Usage: bcp --list [options] module-li...   13.7.2009, 11:59
- - AD   Итак, сделал вырезку некоторых файлов из boost и д...   13.7.2009, 17:30


Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


12 чел. читают эту тему (гостей: 12, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 15.1.2025, 16:09