Подтвердить что ты не робот

Почему компиляторы Haskell не поддерживают детерминированное управление памятью?

Благодаря большому количеству информации о типе информации, почему во время работы Haskell не удается запустить GC для очистки? Должно быть возможно выяснить все способы использования и вставить соответствующие вызовы для выделения/выпуска в скомпилированном коде, правильно? Это позволит избежать накладных расходов на GC среды выполнения.

4b9b3361

Ответ 1

Разумно спросить, могут ли языки функционального программирования делать меньше GC, отслеживая использование. Хотя общая проблема о том, могут ли быть удалены некоторые данные, неразрешима (из-за условного разветвления), безусловно, возможно более статически статически работать и найти больше возможностей для прямого освобождения.

Стоит обратить внимание на работу Мартина Хофманна и команды по проекту "Гарантии мобильных ресурсов", которые сделали выделение по типу памяти (де-ре) распределением основной темы. Тем не менее, вещь, которая заставляет их работать, это то, что Haskell не имеет в своей системе типов --- линейности. Если вы знаете, что входные данные функции являются секретными из остальной части вычисления, вы можете перераспределить память, которую они занимают. Материал MRG особенно хорош, потому что он управляет реалистичным обменным курсом между освобождением от одного типа и распределением для другого, который превращается в хорошее старомодное манипулирование указателем под чисто функциональным внешним видом. Фактически, многие прекрасные алгоритмы бинарных мутаций (например, обратный поворот с указателем, переписывание хвоста и т.д.) Могут быть сделаны для того, чтобы выглядеть чисто функциональными (и проверяться на неприятные ошибки) с использованием этих методов.

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

TL; DR Существуют хорошие типизированные подходы к анализу использования, которые сокращают GC, но Haskell теперь имеет неправильную информацию типа, чтобы быть особенно полезной для этой цели.

Ответ 2

Управление памятью на уровне регионов - это то, что программисты на C и С++ часто заканчивают программированием вручную: выделяют кусок памяти ( "регион", "арена" и т.д.), выделяют в нем отдельные данные, используют их и в конечном итоге освободить весь фрагмент, когда вы знаете, что ни одна из данных не требуется больше. Работа в 90-х годах Тофте, Айкеном и другими (в том числе и с нашими соответствующими коллегами) показала, что можно статически автоматически вывести области распределения и места освобождения ( "вывод области" ) таким образом, чтобы гарантируют, что куски никогда не освобождаются слишком рано и на практике достаточно рано, чтобы избежать слишком большого количества памяти, которая хранится долго после того, как последние данные в ней были необходимы. Например, ML Kit для регионов представляет собой полный стандартный ML-компилятор, основанный на выводе региона. В своей окончательной версии он сочетается с сборкой мусора внутри региона: если статический вывод показывает, что существует долгоживущий регион, используйте внутри него мусорную корзину. Вы получаете свой торт и съедите его тоже: у вас есть сбор мусора для длинных живых данных, но много данных управляется как стек, хотя обычно оно заканчивается кучей.

Ответ 3

Рассмотрим следующий псевдокод:

func a = if some_computation a
    then a
    else 0

Чтобы узнать, является ли a мусором после вызова func a, компилятор должен знать результат some_computation a. Если это может сделать это в общем случае (что требует решения проблемы с остановкой), то не нужно будет вообще испускать код для этой функции, не говоря уже о сборе мусора. Недостаточно информации о типе.

Ответ 4

Нелегко определить время жизни объекта с ленивой оценкой. Компилятор JHC имеет (имеет?) Управление памятью региона, которое пытается освободить память путем освобождения при завершении жизни.

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

Ответ 5

Информация о типе в основном связана с временем компиляции, когда управление памятью - это среда выполнения, поэтому я не думаю, что они связаны друг с другом.