Пользователям Loki::SOA.
От: Bell Россия  
Дата: 25.05.08 13:18
Оценка: 14 (2)
Привет всем.

На днях столкнулся с проблемой, которая, возможно, заинтересует пользователей Loki::SOA.

Решил я прикрутить SOA к очередному проекту. Подправил код, собрал дебаг-версию, запустил, полюбовался на экономию памяти. Собрал релиз, запустил, и словил bad_alloc

Вот минимальный пример, на котором эта проблема у меня повторяется:

Loki::SmallObjAllocator ga;

class Test
{
   int i_;
public:
   Test(int i) : i_(i) {}

   static void* operator new(size_t sz)
   {
      return ga.Allocate(sz);
   }

   static void operator delete(void* ptr, size_t sz)
   {
      ga.Deallocate(ptr, sz);
   }
};

int main()
{
   try
   {
      for(int i = 0; i < 20000000; ++i)
         new Test(i);
   }
   catch(const bad_alloc&)
   {
      cout << "bad_alloc\n";
   }

   cout << "end\n";

   return 0;
}


Платформа: WinXP Prof. SP2, 2GB RAM, 2xPentium D 3GHz
Компилятор VC7.1 + STLPort 4.6.2 (C DinkumSTL проблема тоже повторяется)

Корень всех зол нашелся в функции void* FixedAllocator::Allocate():
void* FixedAllocator::Allocate()
{
    if (allocChunk_ == 0 || allocChunk_->blocksAvailable_ == 0)
    {
        Chunks::iterator i = chunks_.begin();
        for (;; ++i)
        {
            if (i == chunks_.end())
            {
                // Initialize
                chunks_.reserve(chunks_.size() + 1);
                //...
                chunks_.push_back(newChunk); 
                //...


Здесь Chunks — это std::vector<Chunk>.
Похоже, что автор попытался сэкономить память, занимаемую вектором chunks_ за счет постоянного копирования содержимиого вектора при увеличении размера. Наверное, на небольших объемах это имеет смысл Однако, когда счет идет на десятки миллионов мелких объектов, у менеджера памяти просто напросто срывает крышу
Наверное, проблема может крыться и в стандартном аллокаторе, но ИМХО маловероятно, чтобы такая проблема возникала в реализации STL от двух разных разроботчиков
Впрочем, сильно глубоко я не капал

Ах да, проблема исчезает, если закомментарить этот злосчастный reserve.

ЗЫ
Глядя на главу 8 (Don't optimize prematurely) в "C++ Coding Standards", вспоминается фраза "И эти люди запрещают мне ковырять пальцем в носу!" (с)

ЗЗЫ
Еще один полезный момент: при удалении множества объектов имеет смысл отсортировать указатели: FixedAllocator кэширует Chunk, для которого последний раз выполнялась операция Deallocate, так что сортировка указателей увеличивает вероятность попадания в этот кзш, и как следствие — скорость удаления объектов.
Любите книгу — источник знаний (с) М.Горький
Re: Пользователям Loki::SOA.
От: Kswapd Россия  
Дата: 25.05.08 19:53
Оценка: -1 :)
А не является ли само использование SOA типичным случаем преждевременной оптимизации?
Re[2]: Пользователям Loki::SOA.
От: Bell Россия  
Дата: 26.05.08 06:20
Оценка:
Здравствуйте, Kswapd, Вы писали:

K>А не является ли само использование SOA типичным случаем преждевременной оптимизации?


Т.е. использование SOA в любом случае является преждевременной оптимизацией? Если именно это имеется ввиду — мне даже нечего сказать
Если подразумевается что-то другое — то нельзя ли сформулировать мысль яснее?
Любите книгу — источник знаний (с) М.Горький
Re: Пользователям Loki::SOA.
От: Кодт Россия  
Дата: 26.05.08 09:57
Оценка: :)))
Здравствуйте, Bell, Вы писали:

B>Похоже, что автор попытался сэкономить память, занимаемую вектором chunks_ за счет постоянного копирования содержимиого вектора при увеличении размера. Наверное, на небольших объемах это имеет смысл Однако, когда счет идет на десятки миллионов мелких объектов, у менеджера памяти просто напросто срывает крышу

B>Наверное, проблема может крыться и в стандартном аллокаторе, но ИМХО маловероятно, чтобы такая проблема возникала в реализации STL от двух разных разроботчиков
B>Впрочем, сильно глубоко я не капал

B>Ах да, проблема исчезает, если закомментарить этот злосчастный reserve.


Поздравляю! Сукандинавский божок нашёл ещё одну жертву. Божки — они такие, без жертв не могут.

Думаю, что в духе Александреску было бы ввести ещё одну политику — резервирования вектора.
template<class Calculator> // CRTP
struct ReservePolicy
{
    template<class Vec>
    static void reserve(Vec& vec, size_t more)
    {
        size_t const newsize = vec.size()+more;
        if(vec.capacity() < newsize)
            vec.reserve( Calculator::capacity(newsize) );
    }
};

struct DefaultReservePolicy
{
    template<class Vec>
    static void reserve(Vec& vec, size_t more)
    {} // пускай STL позаботится о себе сама
};

struct ScrudgeReservePolicy : ReservePolicy<ScrudgeReservePolicy> // дядюшка Скрудж любит золото...
{
    static size_t capacity(size_t size) { return size; }
};

struct GoldenReservePolicy : ReservePolicy<GoldenReservePolicy> // но золото не знает про дядюшку Скруджа :)
{
    static size_t capacity(size_t size) { return size*161/100; }
};

struct DoubleReservePolicy : ReservePolicy<DoubleReservePolicy>
{
    static size_t capacity(size_t size) { return size*2; }
};
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
Re[2]: Золотое сечение
От: remark Россия http://www.1024cores.net/
Дата: 26.05.08 10:43
Оценка:
Здравствуйте, Кодт, Вы писали:

К>
К>struct GoldenReservePolicy : ReservePolicy<GoldenReservePolicy> // но золото не знает про дядюшку Скруджа :)
К>{
К>    static size_t capacity(size_t size) { return size*161/100; }
К>};
К>



С золотым сечением — это обман. Оно не будет тут работать, т.к. задумывается.
Допустим текущий размер вектора у нас 100, следующий будет 161, следующий — 260. Хоть третий и влазит в сумму первых двух, но второй-то не будет освобожден до выделения третьего, т.к. нам надо скопировать из второго в третий.

Тут должно быть число, удовлетворяющее: 1 + X = X^3. Т.е. четвертый размер должен влазить в сумму первого и второго.
Получается где-то 1.32... Не знаю, есть у этого числа какое-то название.
Первый — 100
Второй — 132
Третий — 174
Четвертый — 230

Третий элемент пока не освобожден, когда выделяем четвертый. А вот объединение первого и второго — как раз по размеру под четвертый.

Очевидно, что Евклид и Леонардо да Винчи НЕ разбираются в компьютерных структурах данных.



1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[2]: Пользователям Loki::SOA.
От: remark Россия http://www.1024cores.net/
Дата: 26.05.08 10:48
Оценка:
Здравствуйте, Kswapd, Вы писали:

K>А не является ли само использование SOA типичным случаем преждевременной оптимизации?


Просто нет слов...


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[3]: Золотое сечение
От: Bell Россия  
Дата: 26.05.08 11:00
Оценка:
Здравствуйте, remark, Вы писали:

R>С золотым сечением — это обман. Оно не будет тут работать, т.к. задумывается.

R>Допустим текущий размер вектора у нас 100, следующий будет 161, следующий — 260. Хоть третий и влазит в сумму первых двух, но второй-то не будет освобожден до выделения третьего, т.к. нам надо скопировать из второго в третий.

Я что-то не понял — зачем рассматиривать 3 блока, и зачем условие "третий и влазит в сумму первых двух"?
Там же все просто как пробка: выделили больший кусок, скопировали из предыдущего, освободили предыдущий
Стандартная стратегия с удвоением размера тоже не вписывается в эти требования...

Или речь о другом?
Любите книгу — источник знаний (с) М.Горький
Re[2]: Пользователям Loki::SOA.
От: Bell Россия  
Дата: 26.05.08 11:09
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Поздравляю! Сукандинавский божок нашёл ещё одну жертву. Божки — они такие, без жертв не могут.


Ну, жертвой я себя не ощущаю
Решение проблемы заняло примерно час, а цели своей я достиг — и в скорости выиграл, и в расходе памяти
Любите книгу — источник знаний (с) М.Горький
Re[4]: Золотое сечение
От: valker  
Дата: 26.05.08 11:15
Оценка:
Здравствуйте, Bell, Вы писали:

B>Я что-то не понял — зачем рассматиривать 3 блока, и зачем условие "третий и влазит в сумму первых двух"?

B>Там же все просто как пробка: выделили больший кусок, скопировали из предыдущего, освободили предыдущий
B>Стандартная стратегия с удвоением размера тоже не вписывается в эти требования...

B>Или речь о другом?


Видимо, речь о том, чтобы использовать пространство в куче оптимальным образом. Есть вероятность, что последовательные аллокации памяти из кучи будут размещаться рядом. В таком случае, при 4-й аллокации размер подобран так, чтобы она "ложилась" на место (вероятно) соседствующих 1-й и 2-й... imho..
... << RSDN@Home 1.2.0 alpha 4 rev. 1090>>
Re[5]: Золотое сечение
От: Bell Россия  
Дата: 26.05.08 11:28
Оценка:
Здравствуйте, valker, Вы писали:

B>>Или речь о другом?


V>Видимо, речь о том, чтобы использовать пространство в куче оптимальным образом. Есть вероятность, что последовательные аллокации памяти из кучи будут размещаться рядом. В таком случае, при 4-й аллокации размер подобран так, чтобы она "ложилась" на место (вероятно) соседствующих 1-й и 2-й... imho..


Ну, между реаллокациями вектора может случиться много всего... Закладываться на это никакого смысла нет... Тоже ИМХО.
Любите книгу — источник знаний (с) М.Горький
Re[4]: Золотое сечение
От: remark Россия http://www.1024cores.net/
Дата: 26.05.08 11:32
Оценка: 25 (4)
Здравствуйте, Bell, Вы писали:

B>Здравствуйте, remark, Вы писали:


R>>С золотым сечением — это обман. Оно не будет тут работать, т.к. задумывается.

R>>Допустим текущий размер вектора у нас 100, следующий будет 161, следующий — 260. Хоть третий и влазит в сумму первых двух, но второй-то не будет освобожден до выделения третьего, т.к. нам надо скопировать из второго в третий.

B>Я что-то не понял — зачем рассматиривать 3 блока, и зачем условие "третий и влазит в сумму первых двух"?

B>Там же все просто как пробка: выделили больший кусок, скопировали из предыдущего, освободили предыдущий
B>Стандартная стратегия с удвоением размера тоже не вписывается в эти требования...

B>Или речь о другом?



Золотое сечение как коэффициент увеличения вектора взялось из следующей особенности.
Допустим у нас коэффициент увеличения 1.5 (меньше золотого сечения), тогда мы получаем следующие размеры: 100, 150, 225... Допустим первые 2 элемента были выделены последовательно в памяти, и при освобождении они объединились в блок размером 250. Тогда третий элемент можно разместить на месте первых двух. Но там остается некоторый неиспользованный кусочек, в данном примере — размером 25.
Допустим у нас коэффициент увеличения 2.0 (больше золотого сечения), тогда мы получаем следующие размеры: 100, 200, 400, 800... Допустим первые 2 элемента были выделены последовательно в памяти, и при освобождении они объединились в блок размером 300. Его не хватит под третий элемент. Под четвертый тоже не хватит места из под первых трех, и т.д. Т.е. всегда надо будет выделять новый блок все большего и большего размера.
Допустим у нас коэффициент увеличения 1.61 (золотое сечение), тогда мы получаем следующие размеры: 100, 161, 260... Допустим первые 2 элемента были выделены последовательно в памяти, и при освобождении они объединились в блок размером 261. Его *в точности* хватит под третий элемент. И дальше это будет постоянно повторяться рекурсивно, т.е. постоянно будем переиспользовать предыдущую память без каких-либо неиспользованных кусочков.

Но когда нам надо копировать данные из предыдущего блока в следующий, т.е. он не будет освобожден пока не выделится следующий, эта схема перестает работать. В такой ситуации коэффициент увеличения должен быть 1.32 (1 + X = X^3).



1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[6]: Золотое сечение
От: Erop Россия  
Дата: 26.05.08 11:36
Оценка:
Здравствуйте, Bell, Вы писали:

B>Ну, между реаллокациями вектора может случиться много всего... Закладываться на это никакого смысла нет... Тоже ИМХО.

Зато есть смысл в гануляции... Но STL это дело не приветсвует, к сожалению
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[6]: Золотое сечение
От: remark Россия http://www.1024cores.net/
Дата: 26.05.08 11:37
Оценка:
Здравствуйте, Bell, Вы писали:

B>Здравствуйте, valker, Вы писали:


B>>>Или речь о другом?


V>>Видимо, речь о том, чтобы использовать пространство в куче оптимальным образом. Есть вероятность, что последовательные аллокации памяти из кучи будут размещаться рядом. В таком случае, при 4-й аллокации размер подобран так, чтобы она "ложилась" на место (вероятно) соседствующих 1-й и 2-й... imho..


B>Ну, между реаллокациями вектора может случиться много всего... Закладываться на это никакого смысла нет... Тоже ИМХО.



Это больше из области теории. Эдакая разминка для мозгов умных дядек.
Тем не менее хоть какой-то аргумент за число 1.61, потому что для коэф. 2 или 1.5 афаик серьезных аргументов нет. Т.е. просто почва для субъективных пристрастий и холиваров.



1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[7]: Золотое сечение
От: Bell Россия  
Дата: 26.05.08 11:52
Оценка:
Здравствуйте, remark, Вы писали:


B>>Ну, между реаллокациями вектора может случиться много всего... Закладываться на это никакого смысла нет... Тоже ИМХО.



R>Это больше из области теории. Эдакая разминка для мозгов умных дядек.

R>Тем не менее хоть какой-то аргумент за число 1.61, потому что для коэф. 2 или 1.5 афаик серьезных аргументов нет. Т.е. просто почва для субъективных пристрастий и холиваров.

Коэффициент напрямую влияет на количество реаллокаций/копирований элементов. Но само собой, общее решение не может подойти в 100% случаев.
В общем, аргумент понятен, спорить смысла нет
Любите книгу — источник знаний (с) М.Горький
Re[3]: Золотое сечение
От: Кодт Россия  
Дата: 26.05.08 11:58
Оценка:
Здравствуйте, remark, Вы писали:

R>Очевидно, что Евклид и Леонардо да Винчи НЕ разбираются в компьютерных структурах данных.


Э, почему Евклид и Леонардо?
Золотое сечение — это асимптотика чисел Фибоначчи.

Мой множитель — 1.61 — чуть меньше φ (~1.61803...), поэтому и получился выезд за пределы.
Возьмём 1.62, и будет всё хорошо.
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
Re[4]: Золотое сечение
От: remark Россия http://www.1024cores.net/
Дата: 26.05.08 12:57
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, remark, Вы писали:


R>>Очевидно, что Евклид и Леонардо да Винчи НЕ разбираются в компьютерных структурах данных.


К>Э, почему Евклид и Леонардо?

К>Золотое сечение — это асимптотика чисел Фибоначчи.

Первые упоминания относятся к Евклиду:
http://ru.wikipedia.org/wiki/%D0%97%D0%BE%D0%BB%D0%BE%D1%82%D0%BE%D0%B5_%D1%81%D0%B5%D1%87%D0%B5%D0%BD%D0%B8%D0%B5

К>Мой множитель — 1.61 — чуть меньше φ (~1.61803...), поэтому и получился выезд за пределы.

К>Возьмём 1.62, и будет всё хорошо.


Всё уже хорошо и при 1.61: 1 + 1.61 > 1.61^2 (=2,5921)
Только я не об этом



1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re: Пользователям Loki::SOA.
От: remark Россия http://www.1024cores.net/
Дата: 26.05.08 19:01
Оценка:
Здравствуйте, Bell, Вы писали:

B>На днях столкнулся с проблемой, которая, возможно, заинтересует пользователей Loki::SOA.

B>Решил я прикрутить SOA к очередному проекту. Подправил код, собрал дебаг-версию, запустил, полюбовался на экономию памяти. Собрал релиз, запустил, и словил bad_alloc


А у тебя какая версия? У тебя возможно какая-то старая версия или вообще — примеры к книге.
На последней версии (http://sourceforge.net/project/showfiles.php?group_id=29557) твой пример не компилируется.
Переписал вот так:
class Test : public Loki::SmallObject<>
{
   int i_;
public:
   Test(int i) : i_(i) {}
};


Всё замечательно отработало, скушав 160 Мб памяти.


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[2]: Пользователям Loki::SOA.
От: Bell Россия  
Дата: 27.05.08 06:38
Оценка:
Здравствуйте, remark, Вы писали:

R>А у тебя какая версия? У тебя возможно какая-то старая версия или вообще — примеры к книге.

Да, у меня более старая версия.
R>На последней версии (http://sourceforge.net/project/showfiles.php?group_id=29557) твой пример не компилируется.
ДА, действительно... Кому щас нужна совместимость сверху вниз?

R>Переписал вот так:

R>
R>class Test : public Loki::SmallObject<>
R>{
R>   int i_;
R>public:
R>   Test(int i) : i_(i) {}
R>};
R>


R>Всё замечательно отработало, скушав 160 Мб памяти.

Да, стратегия реаллокации там несколько изменилась:

std::size_t size = chunks_.size();
// Calling chunks_.reserve *before* creating and initializing the new
// Chunk means that nothing is leaked by this function in case an
// exception is thrown from reserve.
if ( chunks_.capacity() == size )
{
   if ( 0 == size ) size = 4;
   chunks_.reserve( size * 2 );
}



Будет время — будем посмотреть...
Любите книгу — источник знаний (с) М.Горький
Re[3]: Пользователям Loki::SOA.
От: maggot  
Дата: 28.05.08 14:12
Оценка:
Здравствуйте, Bell, Вы писали:

B>Здравствуйте, Кодт, Вы писали:


К>>Поздравляю! Сукандинавский божок нашёл ещё одну жертву. Божки — они такие, без жертв не могут.


B>Ну, жертвой я себя не ощущаю

B>Решение проблемы заняло примерно час, а цели своей я достиг — и в скорости выиграл, и в расходе памяти

А на сколько/во сколько выиграл?
А то у меня в скорости выиграть никак не получается — только в памяти.
В памяти на 25 процентов выигрываю.
А в скорости на столько же проигрываю
Re[4]: Пользователям Loki::SOA.
От: Bell Россия  
Дата: 28.05.08 15:24
Оценка:
Здравствуйте, maggot, Вы писали:

M>А на сколько/во сколько выиграл?

M>А то у меня в скорости выиграть никак не получается — только в памяти.
M>В памяти на 25 процентов выигрываю.
M>А в скорости на столько же проигрываю

Я SOA в 2х проектах только использую: в одном скорость главное, и стратегия простая — сначала создали порядка 100000 объектов, обработали, разом прибили (предварительно отсортировав указатели). На расход памяти даже не смотрел, а вот выигрыш в скорости составил 2-3 раза.

Во втором важнее память, и стратегия такая: сначала создаем много объектов, группируем их, в конце погруппно удаляем. В памяти выигрыш 10%, в скорости проигрыш довольно ощутимый.
Любите книгу — источник знаний (с) М.Горький
Re[2]: Пользователям Loki::SOA.
От: Feonyf  
Дата: 02.06.08 19:33
Оценка: :)
Здравствуйте, Кодт, Вы писали:


К>Поздравляю! Сукандинавский божок нашёл ещё одну жертву. Божки — они такие, без жертв не могут.


http://sourceforge.net/projects/loki-lib/
Development Status : 4 — Beta

я считаю что эта фраза будет уместна, когда будет не beta
Моя строка построения буста:
.\bjam link=static threading=multi runtime-link=static -j %NUMBER_OF_PROCESSORS% --with-filesystem --with-thread --with-date_time address-model=64
Re[3]: Пользователям Loki::SOA.
От: Кодт Россия  
Дата: 03.06.08 07:32
Оценка:
Здравствуйте, Feonyf, Вы писали:

F>http://sourceforge.net/projects/loki-lib/

F>Development Status : 4 — Beta

F>я считаю что эта фраза будет уместна, когда будет не beta


На sourceforge эта штука появилась далеко не сразу... Сперва она скачивалась с сайта автора (www.moderncppdesign.com), потом силами энтузиастов её стали делать всеядной — под разные платформы и компиляторы. Никакого статуса "альфа-бета-релиз" у Loki ещё не было.
Но уже тогда божок собирал кровавую жатву.
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
Re[4]: Пользователям Loki::SOA.
От: Bell Россия  
Дата: 03.06.08 07:39
Оценка:
Здравствуйте, Кодт, Вы писали:

К>...

К>Но уже тогда божок собирал кровавую жатву.
Слушай, я ни разу не видел от тебя высказываний в таком ключе ни по одной теме
Чем тебе так насолил Александреску со своей Loki? ИМХО к подобным продуктам в любом случае нужно относится без фанатизма, и держать напильник под рукой...

ЗЫ
просто интересно
Любите книгу — источник знаний (с) М.Горький
Re[5]: Пользователям Loki::SOA.
От: Кодт Россия  
Дата: 03.06.08 08:57
Оценка:
Здравствуйте, Bell, Вы писали:

К>>Но уже тогда божок собирал кровавую жатву.

B>Слушай, я ни разу не видел от тебя высказываний в таком ключе ни по одной теме
B>Чем тебе так насолил Александреску со своей Loki? ИМХО к подобным продуктам в любом случае нужно относится без фанатизма, и держать напильник под рукой...

Это не вопрос того, что Александреску насолил или не насолил. Он просто выложил грабли в публичный доступ, и я в этом вижу не его злой умысел, а приколы одноимённого скандинавского божка.
А поскольку грабли прикрыты слоем очень красивых решений, то тем обиднее на них наступать.

Представляешь, если в бусте или STL были бы разбросаны такие подарки?
Кстати, в Dinkumware STL для VC6 — были. Что стоит, например, сортировка списка, игнорирующая предикат...
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
Re[5]: Золотое сечение
От: gear nuke  
Дата: 15.06.08 15:12
Оценка:
Здравствуйте, remark,

Еще зависит от аллокатора нижнего уровня. Виндовый выделяет блоками кратными степени 2, за вычетом заголовка, а в конечном счёте все сводится к размеру физстраниц.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re: Пользователям Loki::SOA.
От: рыбак  
Дата: 16.06.08 07:29
Оценка:
Здравствуйте, Bell, Вы писали:

B>Привет всем.


Привет

B>Платформа: WinXP Prof. SP2, 2GB RAM, 2xPentium D 3GHz

B>Компилятор VC7.1 + STLPort 4.6.2 (C DinkumSTL проблема тоже повторяется)

B>Корень всех зол нашелся в функции void* FixedAllocator::Allocate():

B>
B>void* FixedAllocator::Allocate()
B>{
B>    if (allocChunk_ == 0 || allocChunk_->blocksAvailable_ == 0)
B>    {
B>        Chunks::iterator i = chunks_.begin();
B>        for (;; ++i)
B>        {
B>            if (i == chunks_.end())
B>            {
B>                // Initialize
B>                chunks_.reserve(chunks_.size() + 1);
B>                //...
B>                chunks_.push_back(newChunk); 
B>                //...
B>


А мне кажется что это ошибка STL. Метод reserve должен как раз выделять столько памяти, чтобы минимизировать реалокацию. А именно например if( needreallocation ) newreserve = min(текущийreserve*3/2, желаемыйreserve).
По крайней мере до этого поста я именно так и думал
Re[2]: поправочка
От: рыбак  
Дата: 16.06.08 07:31
Оценка:
if( needreallocation ) newreserve = max(текущийreserve*3/2, желаемыйreserve).
Re[2]: Пользователям Loki::SOA.
От: Bell Россия  
Дата: 16.06.08 07:40
Оценка:
Здравствуйте, рыбак, Вы писали:

Р>А мне кажется что это ошибка STL.



Р>Метод reserve должен как раз выделять столько памяти, чтобы минимизировать реалокацию. А именно например if( needreallocation ) newreserve = min(текущийreserve*3/2, желаемыйreserve).


Метод reserve должен выделять столько памяти, сколько попросят. Объем запрашиваемой памяти (стратегию реаллокации) должен определять вызывающий код. Кстати приведенная тобой формула ни в коей мере не решает исходной проблемы, потому как min (size()*3/2, size()+1) == size()+1

Р>По крайней мере до этого поста я именно так и думал

Если не навязывать вектору свою стратегию реаллокации, то при необходимости он выделяет память в объеме size() * coef. Наиболее популярные значение coef - 2, 1.5.
Любите книгу — источник знаний (с) М.Горький
Re[3]: Пользователям Loki::SOA.
От: рыбак  
Дата: 16.06.08 07:48
Оценка:
Здравствуйте, Bell, Вы писали:

B>Здравствуйте, рыбак, Вы писали:


Р>>А мне кажется что это ошибка STL.

B>

Р>>Метод reserve должен как раз выделять столько памяти, чтобы минимизировать реалокацию. А именно например if( needreallocation ) newreserve = min(текущийreserve*3/2, желаемыйreserve).


B>Метод reserve должен выделять столько памяти, сколько попросят. Объем запрашиваемой памяти (стратегию реаллокации) должен определять вызывающий код. Кстати приведенная тобой формула ни в коей мере не решает исходной проблемы, потому как min (size()*3/2, size()+1) == size()+1


да, я ошибся, конечно же max(текущийreserve*3/2, желаемыйreserve).

Р>>По крайней мере до этого поста я именно так и думал

B>Если не навязывать вектору свою стратегию реаллокации, то при необходимости он выделяет память в объеме size() * coef. Наиболее популярные значение coef - 2, 1.5.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.