Информация об изменениях

Сообщение Re[46]: Nemerle через 5 лет - выстрелит или скончается? от 10.10.2014 3:42

Изменено 10.10.2014 4:27 VladD2

Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Бесплатное освобождение это когда ничего не нужно ни перемещать, ни бегать по развесистым графам, ни мир останавливать.

EP>То есть кроме выделения не производится абсолютно никаких операций.

Дык при освобождении ничего и не делается. Точнее даже самого освобождения нет. По графам бегают в других потоках. При этом остальные потоки не останавливаются. И мертвых объектов в этом графе нет. Мир останавливается не всегда. Есть конкурентные GC. А те что останавливают, делают это на очень короткие промежутки времени и исключительно для дефрагментации памяти, о которой в С++ даже мечтать нельзя.

Ты разберись в вопросе прежде чем членами мериться. Для кого я вот эту статью
Автор: Чистяков Влад (VladD2 )
Дата: 02.03.06
писал?

EP>Pool это когда есть что-то типа free list'а уже готовых кусочков, и вся аллокация/деаллокация сводится к практически бесплатным pop/push в этот free list.

EP>Ни в Java, ни в .NET, GC и близко не приближается по производительности к Pool'у — отсюда и все эти заморочки с garbage-free и т.п.

Ох, ох, ох. Еще один спорщик черпающий знания перед ответом в Википедии. Ты все напутал. Free list — это как раз простейший алгоритм используемый в С-шных/С++-ных менеджерах памяти. Именно он вызывает фрагментацию хипов и тормоза.

Пул же это когда память выделяется большим блоком (пулом) и нарезается для конкретных нужд. Ты ниже это назвал Region-based. Free list же не имеет к нему никакого отношения. Это всего лишь тупой и тормозной алгоритм из дремучих веков.

А вот в GC используют Region-based (если тебе так понятнее) принцип. Выделение памяти в GC — это всего лишь увеличение указателя на начало свободной памяти в хипе. Освобождение вообще не просходит.

Так что да, в дотнете используется самый быстрый в мире алгоритм распределения памяти. А платим за этом мы не временем освобождения памяти, а временем которое процессор тратит на выполнение кода который компилятор (джит или нген) помещает в местах где могут модифицироваться ссылки. Нужно это для того, чтобы могли работать не тривиальные алгоритмы не тормозящие мир при обходе и дефрагментации.

Дефрагментация и тем более обход графа обычно идут в параллельных потоках. Учитывая, что голов у современных процессоров довольно много, это не сильно напрягает рабочие потоки.

Быстрее, как я уже говорил, только пулы (Region-based, если тебе так угодно) которые создаются под группу объектов которые имеют одинаковый срок жизни. При этом можно уничтожить весь пул, а не возиться с каждый отдельным объектом.

Но тут есть ряд проблем. Не все алгоритмы позволяют использовать такой подход. Нужно знать каков максимальный объем пула потребуется алгоритму. Малейшая ошибка может привести к работе с освобожденной памятью. В GC же этих проблем не существует.

По жизни в С++, если нужно строить графы объектов, обычно используют обычную кучу и один из способов полуавтоматического управления памятью (смартуказатели со стратегиями владения или подсчет ссылок). Например, в броузерах обычно используется именно подсчет ссылок. Причем идет тенденция к переходу на GC.

EP>Да, но используются они совершенно по-разному.

EP>В C++ создавая вектор N объектов конкретного класса происходит ровно одна аллокация (не учитывая внутренние под-объекты в куче). В C# же, а уж тем более в Java, будет N+1 аллокация — одна на массив указателей, и по одной на каждый объект.

Ну, это явное заблуждение. В Шарпе (точнее в дотнете) есть варианты. Можно создать структуру и она будет точно так же размещена в массиве. Мы частенько пользуемся таким подходом. К сожалению этот подход не работает, если речь идет о иерархиях объектов. Тут только ссылки.

EP>Самый быстрый аллокатор это Region/Arena/Zone. Аллокация это просто увеличение счётчика текущей позиции в свободной памяти на выделяемый размер, а деалокации нет, то есть бесплатная.

EP>Опять же, по производительности GC и рядом не стоит с регионами, и разница отнюдь не "некоторое количество тактов" — это как небо и земля.

Очень смешно. Я тебя расстрою. В GC именно так память и выделяется. Разве что интерлок используется, для потокобезопасности.

Region-based (он же пул) без сборки мусора — это очень специфичная штука подходящая не очень часто. По крайней мере я за всю жизнь видел пару применений этого подхода. Собственно повторяться не буду, так как говорил об этом выше.

Так что, как говорится, не учи отца ... делать детей.

Ты наверно еще в школу ходил, когда я делал реально универсальные "самые быстрые в мире" хипы
Автор(ы): Чистяков Владислав
Дата: 26.11.2002
, и изучал
Автор: Чистяков Влад (VladD2 )
Дата: 02.03.06
как работает GC дотнета. Так что я выбор делал осознанно и знаю о чем говорю. Можешь себя не утруждать безграмотными ликбезами.

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

И я точно знаю, что грамотно написанные дотнет-приложения отстают от аналогичных С++-приложений очень незначительно и виной тому слабые оптимизации компиляторов, а отнюдь не GC. Есть приложения в которых сборка мусора становится узким местом, но это скорее алгоритмическая проблема. Она бы вылезла и в С++.

При этом я отдаю себе отчет, что плюсы имеют больше возможностей по оптимизаций и лучшие компиляторы С/С++ порождают лучшей код нежели джит дотнета. Но за все это приходится платить. Скорость заработки на плюсах несравнимо ниже. Уровень работы значительно ниже.

VD>>Для отдельных задач конечно можно создать более быстрые решения, но в общем случае они не работают.


EP>Непонятно о каком общем случае идёт речь — если GC это сферически общий случай, тогда и Region-based — это такой же общий случай.

EP>А если по хорошему — то оба способа хорошо применимы только для определённых сценариев, что мы и видим на практике.

GC — это общее решение автоматического проблемы управления памятью. Она тебе просто перестает волновать. Нужно помнить только то, что не стоит складывать все выделенные объекты в динамический массив ссылка на который помещена в статическую переменную .

Основан он на том же пуле. Люди не одну плешь себе на темени проели стараясь сделать GC более быстрым и не делающим заметных задержек программы (что намного сложнее нежели просто быстрый).

Обогнать его могут далеко не только лишь все (ц). А вот накосячить управляя памятью вручную может каждый. Чтобы это не случилось люди используют разные техники вроде смартпоинтров, что выливается в накладные расходы сравнимые с райт-берьерами в GC. Подсчет ссылок обычно более медленный механизм нежели GC. Если бы это было не так, то GC и строили на базе подсчета ссылок, так как реализация этого способа элементарна.
Re[46]: Nemerle через 5 лет - выстрелит или скончается?
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Бесплатное освобождение это когда ничего не нужно ни перемещать, ни бегать по развесистым графам, ни мир останавливать.

EP>То есть кроме выделения не производится абсолютно никаких операций.

Дык при освобождении ничего и не делается. Точнее даже самого освобождения нет. По графам бегают в других потоках. При этом остальные потоки не останавливаются. И мертвых объектов в этом графе нет. Мир останавливается не всегда. Есть конкурентные GC. А те что останавливают, делают это на очень короткие промежутки времени и исключительно для дефрагментации памяти, о которой в С++ даже мечтать нельзя.

Ты разберись в вопросе прежде чем членами мериться. Для кого я вот эту статью
Автор: Чистяков Влад (VladD2 )
Дата: 02.03.06
писал?

EP>Pool это когда есть что-то типа free list'а уже готовых кусочков, и вся аллокация/деаллокация сводится к практически бесплатным pop/push в этот free list.

EP>Ни в Java, ни в .NET, GC и близко не приближается по производительности к Pool'у — отсюда и все эти заморочки с garbage-free и т.п.

Ох, ох, ох. Еще один спорщик черпающий знания перед ответом в Википедии. Ты все напутал. Free list — это как раз простейший алгоритм используемый в С-шных/С++-ных менеджерах памяти. Именно он вызывает фрагментацию хипов и тормоза.

Пул же это когда память выделяется большим блоком (пулом) и нарезается для конкретных нужд. Ты ниже это назвал Region-based. Free list же не имеет к нему никакого отношения. Это всего лишь тупой и тормозной алгоритм из дремучих веков.

А вот в GC используют Region-based (если тебе так понятнее) принцип. Выделение памяти в GC — это всего лишь увеличение указателя на начало свободной памяти в хипе. Освобождение вообще не просходит.

Так что да, в дотнете используется самый быстрый в мире алгоритм распределения памяти. А платим за этом мы не временем освобождения памяти, а временем которое процессор тратит на выполнение кода который компилятор (джит или нген) помещает в местах где могут модифицироваться ссылки. Нужно это для того, чтобы могли работать не тривиальные алгоритмы не тормозящие мир при обходе и дефрагментации.

Дефрагментация и тем более обход графа обычно идут в параллельных потоках. Учитывая, что голов у современных процессоров довольно много, это не сильно напрягает рабочие потоки.

Быстрее, как я уже говорил, только пулы (Region-based, если тебе так угодно) которые создаются под группу объектов которые имеют одинаковый срок жизни. При этом можно уничтожить весь пул, а не возиться с каждый отдельным объектом.

Но тут есть ряд проблем. Не все алгоритмы позволяют использовать такой подход. Нужно знать каков максимальный объем пула потребуется алгоритму. Малейшая ошибка может привести к работе с освобожденной памятью. В GC же этих проблем не существует.

По жизни в С++, если нужно строить графы объектов, обычно используют обычную кучу и один из способов полуавтоматического управления памятью (смартуказатели со стратегиями владения или подсчет ссылок). Например, в броузерах обычно используется именно подсчет ссылок. Причем идет тенденция к переходу на GC.

EP>Да, но используются они совершенно по-разному.

EP>В C++ создавая вектор N объектов конкретного класса происходит ровно одна аллокация (не учитывая внутренние под-объекты в куче). В C# же, а уж тем более в Java, будет N+1 аллокация — одна на массив указателей, и по одной на каждый объект.

Ну, это явное заблуждение. В Шарпе (точнее в дотнете) есть варианты. Можно создать структуру и она будет точно так же размещена в массиве. Мы частенько пользуемся таким подходом. К сожалению этот подход не работает, если речь идет о графах объектов. Тут только ссылки.

EP>Самый быстрый аллокатор это Region/Arena/Zone. Аллокация это просто увеличение счётчика текущей позиции в свободной памяти на выделяемый размер, а деалокации нет, то есть бесплатная.

EP>Опять же, по производительности GC и рядом не стоит с регионами, и разница отнюдь не "некоторое количество тактов" — это как небо и земля.

Очень смешно. Я тебя расстрою. В GC именно так память и выделяется. Разве что интерлок используется, для потокобезопасности.

Region-based (он же пул) без сборки мусора — это очень специфичная штука подходящая не очень часто. По крайней мере я за всю жизнь видел пару применений этого подхода. Собственно повторяться не буду, так как говорил об этом выше.

Так что, как говорится, не учи отца ... делать детей.

Ты наверно еще в школу ходил, когда я делал реально универсальные "самые быстрые в мире" хипы
Автор(ы): Чистяков Владислав
Дата: 26.11.2002
, и изучал
Автор: Чистяков Влад (VladD2 )
Дата: 02.03.06
как работает GC дотнета. Так что я выбор делал осознанно и знаю о чем говорю. Можешь себя не утруждать безграмотными ликбезами.

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

И я точно знаю, что грамотно написанные дотнет-приложения отстают от аналогичных С++-приложений очень незначительно и виной тому слабые оптимизации компиляторов, а отнюдь не GC. Есть приложения в которых сборка мусора становится узким местом, но это скорее алгоритмическая проблема. Она бы вылезла и в С++.

При этом я отдаю себе отчет, что плюсы имеют больше возможностей по оптимизаций и лучшие компиляторы С/С++ порождают лучшей код нежели джит дотнета. Но за все это приходится платить. Скорость заработки на плюсах несравнимо ниже. Уровень работы значительно ниже.

VD>>Для отдельных задач конечно можно создать более быстрые решения, но в общем случае они не работают.


EP>Непонятно о каком общем случае идёт речь — если GC это сферически общий случай, тогда и Region-based — это такой же общий случай.

EP>А если по хорошему — то оба способа хорошо применимы только для определённых сценариев, что мы и видим на практике.

GC — это общее решение автоматического проблемы управления памятью. Она тебе просто перестает волновать. Нужно помнить только то, что не стоит складывать все выделенные объекты в динамический массив ссылка на который помещена в статическую переменную .

Основан он на том же пуле. Люди не одну плешь себе на темени проели стараясь сделать GC более быстрым и не делающим заметных задержек программы (что намного сложнее нежели просто быстрый).

Обогнать его могут далеко не только лишь все (ц). А вот накосячить управляя памятью вручную может каждый. Чтобы это не случилось люди используют разные техники вроде смартпоинтров, что выливается в накладные расходы сравнимые с райт-берьерами в GC. Подсчет ссылок обычно более медленный механизм нежели GC. Если бы это было не так, то GC и строили на базе подсчета ссылок, так как реализация этого способа элементарна.