Комментарии 21
Расскажете о своем опыте работы с алокаторами?
как нет-то :D
в прямом смысле замедляет работу программы в соотношении примерно 1 к 1
рост фрагментации памяти не должен превышать 2% в час
может мы обидели кого-то зря (ц)
но фразы "примерно 1 к 1" и "2% в час" - это откровенный бред! и дальше можно уже не читать...
но автора спасает фраза "TC-аллокатор переносит работу с памятью на уровень отдельного потока, предоставляя каждому собственный пул памяти. Помимо избавления от системного new/malloc, он также снижает затраты на синхронизацию", и тут уже можно что-то сказать по Теме.
короче, дальше опять будут ссылки. они позволят вам САМОСТОЯТЕЛЬНО запустить код и убедиться в ВОТ ТАКОМ росте производительности... но если это обидно, то ссылки можно не открывать ;)
итак.
первое. ders::mem_pool - это thread-local allocator, который еще в 2009 году добился 339.5 кратного роста производительности https://ders.by/cpp/mtprog/mtprog.html#3.1.1
второе. ders::off_pool - это использующий СМЕЩЕНИЯ thread-local allocator, позволивший реализовать хеш-таблицу с транзакциями с тридцатикратным ростом производительности! и это прямо сегодня, на современных платформах https://ders.by/cpp/memdb/memdb.html#5.2
ЗЫ уверен, вы понимаете, что мои 339.5 и 30 раз - это не голословные "примерно 1 к 1" и "2% в час" автора ;))
В смысле каждый процент фрагментации примерно на столько же замедляет весь билд. Проверено нв десятке шипнутых игр и сотнях разных конфигов 10% - минус пять фпс в релизе. Извините конкретно Вашей реализации в играх не было, я не могу тут ничего ответить. Возможно мы действительно что-то упустили, тлсф как-то попривычнее будет.
не хватает примеров где полёт буллет на какойто реализации или система частиц отьест 5 фпс
тоесть буллет прилетела и проигрались частички плюс дождик на локации минус 15 фпс, если еще рядом костер поставить ну допустим тоже на частичках
этого добра навалом, даже ходить никуда не надо, просто сделайте там стандартный new/malloc, вот синтетика ваших столкновений
https://quick-bench.com/q/ScPhKA9CEtFcZp4DLLgTVBhFVfU
по задачке буллет у меня так получилось,
Скрытый текст
if(flyBullet)//trigger
{
// printf("%f\n",Distance);//debug
vec3 offsetbullet = Normalize(Subv3(Obj2[pickedID].pos,Obj1.pos));
offsetbullet=Mulv3c(offsetbullet, 1.0f);
if( Distance(Obj2[pickedID].pos,Obj1.pos)) { //distance for exit fly
SetPosRotScale(&Obj1);
flyBullet=false;//exittriggerResumePosition
}
else if (Distance(Obj2[pickedID].pos,Obj1.pos)) //distance for fly
SetPosRotScale(&Obj1);//fly
}
это без библитеки и коллайдеров
допустим у нас есть по екземпляру каждого обьекта, типо все для текущей сцены по 1 штуке, если это уникальные локации они как я понимаю вообще не в счет
тогда поидее проблема с памятью появляется только когда сцена меняется, типо надо прогрузить другую сцену
может еще есть вариант сгенерировать эту анимацию на геометрическом шейдере кинув в него 2 координаты от и до и на шейдере от координаты сгенерировать буллет и вернуть точку, это я не пробовал пока читал что есть возможность генерировать от точки на шейдере примитивы
Прочитал статью, ощущение что прочитал Александреску, вроде понятно, вроде законченно, но ведь точно есть изъян, но где?!
Всё-таки представление о сборщиках мусора лучше получать из книги новее. "The Garbage Collection Handbook" подходит.
можно еще тут глянуть https://github.com/microsoft/DirectX-Graphics-Samples
Прочитал, очень интересно. Про часть аллокаторов знал из курса по операционным системам, часть увидел впервые. И ещё очень понравилась привязка к реальным играми и цифрам - понятно, что цифры очень сильно зависят от конкретного применения, но порядок эффекта тоже полезно знать.
А то, например, я когда-то слышал про аллокатор с размерами как числа Фибоначчи, но не задумывался над тем, что он может быть лучше аллокатора с размерами по степеням двойки.
Кажется, Вы из своих статей на хабре уже можете книжку про геймдев собрать :) Я не про скучную часть с редактором и корректировками, а про формат - одним большим куском, чтобы взять и всё прочитать, а не надеятся что я вдруг не пропущу ещё одну статью на хабре.
Спасибо за статью. Добавил в закладки.
"ручное моделирование деревьев" - ...ну оно "такое себе"
Статья безусловно интересная, но с примерами какая-то беда (нейронка генерила?)
Пример:
class StackAllocator {
public:
StackAllocator(size_t size) {
...
this->size = size;
}
...
void* allocate(size_t size) {
if (top + size <= (char*)memory + this->size) {
...
}
return nullptr; // Нет памяти
}
void deallocate(void* ptr) {
assert(ptr == top);
top = (char*)top - sizeof(ptr); // Освобождение
}
...
private:
void* memory;
void* top;
};
Член size не объявлен
В deallocate внезапно используем sizeof. Наверно всё таки нужна история аллокаций?
Указатели зачем-то void*, а потом касты везде насыпаны
Также не раскрыта тема использования без отстрела ног: когда вызывать деструкторы? Как подружить с контейнерами?
Мдя, недосмострел, спасибо. Надо поправить, примеры из корпвики все, чисто для понимания
А насчет отстрела ноги и дружбы с контейнерами тема настолько общая и неинтересная, что даже не знаю стоит ли её обсуждать. Во первых получится скучно, я вижу это по студентам - на лекции по работе с контейнерами ходит едва ли треть группы. Вы же понимаете, что читать сто первый пост о том как надо работать с контейнерами в сто раз скучнее, или он должен нести какойто рокетсайнс уровня конфы. Во вторых общие решения на то и общие, что все про них знают, частные случаи уже интереснее, но они обычно опираются на различные баги, жуткие случаи и байки из прода. Тащить сюда баги ? так хабр не жалобная книга, да и каждого тут таких багов вагон с прицепом
В далёком 2006 мне надо было портировать очередную жей2эме игру на платформу где использовался с++. Все контора этим занималась - пост продакшн на мобилках тех времён. Не помню точно какая возможно это был Соник. Так вот на большинстве телефонов все работало норм, но была платформа где было медленно. Я залогировал (построил гистограмму) всех аллокаций, ну к моему счастью 95% были блоки на 12 байт. Ничего не зная про все эти типы аллокаторов я просто совместил блочный и фри лист, додуматься до этого не много ума надо. Метаданные (связный список свободных блоков) был размещен в самих блоках одинакового размера. Я сделал список на массиве и по сути указатель на следующий блок это индекс в массиве. Т.е. был большой массив блоков по 12 байт, когда блоки свободны они хранили индекс следующего блока, а когда заняты какие-то данные.
Померял сколько нужно блоков, ну как померял увеличивал размер пула по фибоначи пока не перестало крашится потом увеличил ещё разок на всякий случай и успокоился. Игра стала летать. Т.к. я заранее сделал размер пула точно больше чем нужно блоков, то даже выкинул проверку на нет блоков.
С тех пор никогда больше мне не требовалось заниматься подобной магией, кроме трэйдинга по причине лоу лэтенси требований. Так вот все эти аллокаторы нужны либо в играх либо в трэйдинге, звук иногда, но там можно просто все заранее преаллоцировать. Короче в обычной жизни даже стандартного аллокатора хватает, не говоря о том что есть джейемалок если обычный не устраивает.
все эти аллокаторы нужны либо в играх либо в трэйдинге... Короче в обычной жизни даже стандартного аллокатора хватает
увы, но нет:
thread-local allocator полезен всем многопоточным приложениям. точно так же, как однопоточным не нужен std::shared_ptr с его атомиками.
а в однопоточных числодробилках mem_pool существенно увеличивает скорость и заметно уменьшает расход памяти. например, возьмите https://ders.by/cmpr/cpt/cpt.html и уберите вызов mp_set_memory_functions().
Все число дробилки которые я кодил или видел вообще не требует динамической аллокации, если точнее, то она конечно нужна т.к. размер стэка ресурс ограниченный. Все ж таки буфера алоциртся в хипе, но 1 раз перед началом расчетов. Поэтому фиолетово сколько у вас там потоков. Я не видел успешных число дробилок которые чё то динамически аллоцируют посреди рассчетов в таких количествах когда нужно думать об аллокаторах.
Динамическая аллокация жизненно необходима в событийных системах, но если нет жёстких требований по лэтенси то и стандартного аллокатора достаточно. А когда лэтенси важно то первым делом аллокации вообще выпиливают и только когда от них нельзя или дорого избавиться начинают думать над аллокатором.
Я не видел успешных число дробилок которые чё то динамически аллоцируют посреди рассчетов в таких количествах когда нужно думать об аллокаторах
вы что-нибудь слышали о GMP?
https://en.wikipedia.org/wiki/GNU_Multiple_Precision_Arithmetic_Library
Game++. Dancing with allocators