Spec-Zone.ru › Haskell 8

7.7. Запуск скомпилированной программы

Для создания исполняемого файла система GHC компилирует ваш код, а затем связывает его с нетривиальной системой выполнения (RTS), которая обрабатывает управление памятью, планирование потоков, профилирование и так далее.

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

7.7.1. Настройка опций RTS

Существует четыре способа настройки опций RTS:

  • в командной строке между +RTS ... -RTS, при запуске программы (Настройка опций RTS в командной строке)
  • во время компиляции, используя -with-rtsopts=⟨opts⟩ (Настройка опций RTS во время компиляции)
  • с помощью переменной среды GHCRTS (Настройка опций RTS с переменной среды GHCRTS)
  • переопределением «хуков» в системе выполнения («Хуки» для изменения поведения RTS)

7.7.1.1. Настройка опций RTS в командной строке

Если вы правильно установили флаг -rtsopts[=⟨none|some|all|ignore|ignoreAll⟩] при линковке (см. Опции, влияющие на линковку), вы можете указать опции RTS в командной строке при запуске вашей программы.

Когда ваша Haskell-программа запускается, RTS извлекает аргументы командной строки, заключенные между +RTS и -RTS, как свои собственные. Например:

$ ghc prog.hs -rtsopts
[1 of 1] Compiling Main             ( prog.hs, prog.o )
Linking prog ...
$ ./prog -f +RTS -H32m -S -RTS -h foo bar

RTS заберет -H32m -S для себя, а оставшиеся аргументы -f -h foo bar будут доступны вашей программе, если/когда она вызовет System.Environment.getArgs.

Опция -RTS не требуется, если опции системы выполнения простираются до конца командной строки, как в этом примере:

% hls -ltr /usr/etc +RTS -A5m

Если вы абсолютно хотите, чтобы все остальные опции в командной строке попадали в программу (а не в RTS), используйте --RTS.

Как всегда, для опций RTS, принимающих ⟨размер⟩: если последняя буква ⟨размера⟩ — K или k, умножьте на 1000; если M или m, на 1 000 000; если G или G, на 1 000 000 000. (А любые переполнения счетчиков — ваша вина!)

Указание опции RTS +RTS -? выведет доступные в вашей программе опции RTS (которые различаются в зависимости от того, как вы компилировали).

Примечание

Поскольку GHC сам скомпилирован GHC, вы можете изменить опции RTS в компиляторе, используя обычное +RTS ... -RTS сочетание. Например, чтобы установить максимальный размер кучи для компиляции в 128М, добавьте +RTS -M128m -RTS в командную строку.

7.7.1.2. Настройка опций RTS во время компиляции

GHC позволяет изменить опции RTS по умолчанию для программы во время компиляции, используя флаг -with-rtsopts (Опции, влияющие на линковку). Частое применение — установить для программы значения кучи и/или стека по умолчанию, превышающие значения по умолчанию. Например, чтобы установить -H128m -K64m, свяжите с -with-rtsopts="-H128m -K64m".

7.7.1.3. Настройка опций RTS с переменной среды GHCRTS

GHCRTS

Если флаг -rtsopts установлен на значение, отличное от none или ignoreAll при линковке, опции RTS также берутся из переменной среды GHCRTS. Например, чтобы установить максимальный размер кучи в 2Г для всех программ, скомпилированных GHC (используя оболочку типа sh):

GHCRTS='-M2G'
export GHCRTS

Опции RTS, взятые из переменной среды GHCRTS, можно переопределить опциями, указанными в командной строке.

Подсказка

Установить что-то вроде GHCRTS=-M2G в вашей среде — удобный способ предотвратить рост Haskell-программы за пределы реальной памяти вашего компьютера, что легко сделать случайно, и это может привести к замедлению работы компьютера до момента, пока операционная система не решит убить процесс (и вы надеетесь, что она убьет правильный).

7.7.1.4. «Хуки» для изменения поведения RTS

GHC позволяет осуществлять элементарное управление определёнными параметрами RTS для любой конкретной программы путём компиляции «хука», который вызывается системой выполнения. RTS содержит определения заглушек для этих хуков, но написав свою собственную версию и связав её в командной строке GHC, вы можете переопределить значения по умолчанию.

Из-за особенностей связи DLL эти хуки не работают в Windows, когда программа построена динамически.

7.7.1.4.1. События выполнения

Вы можете изменить сообщения, выводимые, когда система выполнения «вылетает», например, при переполнении стека. Хуки для них следующие:

void OutOfHeapHook(unsigned long, unsigned long)

Сообщение о переполнении кучи.

void StackOverflowHook(long int)

Сообщение о переполнении стека.

void MallocFailHook(long int)

Сообщение, выводимое, если malloc терпит неудачу.

7.7.1.4.2. Вывод журналов событий

Кроме того, GHC позволяет указать способ записи данных журналов событий (см. -l ⟨flags⟩) через пользовательский EventLogWriter:

EventLogWriter

Пункт назначения данных журналов событий.

void initEventLogWriter(void)

Инициализирует ваш EventLogWriter. Это необязательно.

bool writeEventLog(void *eventlog, size_t eventlog_size)

Передает буферизованные данные журнала событий вашему записывателю журнала событий. Возвращает true при успехе. Требуется для пользовательского EventLogWriter.

void flushEventLog(void)

Очистить буферы (если есть) вашего пользовательского EventLogWriter. Это может быть NULL.

void stopEventLogWriter(void)

Вызывается, когда запись в журнал событий должна завершиться. Это может быть NULL.

Для использования EventLogWriter API RTS предоставляет следующие функции:

EventLogStatus eventLogStatus(void)

Определить, поддерживает ли текущая система выполнения журнал событий (например, был ли текущий исполняемый файл связан с -eventlog) и, если он поддерживается, записывается ли он в данный момент.

bool startEventLogging(const EventLogWriter *writer)

Начать запись событий в указанный EventLogWriter. Возвращает true при успехе или false, если другой записыватель уже настроен.

void endEventLogging()

Разборка активного EventLogWriter.

где enum EventLogStatus:

EventLogStatus
  • EVENTLOG_NOT_SUPPORTED: Система выполнения не была скомпилирована с поддержкой журналов событий.
  • EVENTLOG_NOT_CONFIGURED: EventLogWriter еще не настроен.
  • EVENTLOG_RUNNING: EventLogWriter настроен и работает.

7.7.2. Дополнительные опции RTS

--install-signal-handlers=⟨yes|no⟩

Если yes (по умолчанию), RTS устанавливает обработчики сигналов для перехвата таких событий, как Ctrl-C. Эта опция полезна в основном для использования кода Haskell как DLL и настройки собственных обработчиков сигналов.

Обратите внимание, что даже с --install-signal-handlers=no, таймерный сигнал RTS все еще включён. Таймерный сигнал — это либо SIGVTALRM, либо SIGALRM, в зависимости от конфигурации RTS и возможностей ОС. Для отключения таймерного сигнала используйте опцию RTS -V0 (см. -V ⟨secs⟩).

--install-seh-handlers=⟨yes|no⟩

Если yes (по умолчанию), RTS в Windows устанавливает обработчики исключений для перехвата необработанных исключений с помощью механизма обработки исключений Windows. Эта опция полезна в основном для использования кода Haskell как DLL и предотвращения некорректного завершения вашей программы на ошибках, таких как segfaults.

--generate-crash-dumps

Если да (по умолчанию), RTS в Windows будет генерировать дамп ядра при любом сбое. Эти дампы можно просматривать с помощью отладчиков, таких как WinDBG. Дампы записывают весь код, регистры и информацию о потоках в момент сбоя. Обратите внимание, что это подразумевает --install-seh-handlers=yes.

--generate-stack-traces=<yes|no>

Если да (по умолчанию), RTS в Windows будет генерировать трассировку стека при сбоях, если включена обработка исключений. Для получения дополнительной информации в скомпилированных исполняемых файлах, коде C или DLL должны быть доступны символы.

--disable-delayed-os-memory-return

Если задано, использует MADV_DONTNEED вместо MADV_FREE на платформах, где это приводит к более точной оценке резидентного использования памяти программой, как показано в инструментах отслеживания использования памяти (например, столбец RSS в top и htop).

Использование этого, как ожидается, немного замедлит программу.

В Linux MADV_FREE новее и быстрее, потому что он может избежать обнуления страниц, если они повторно используются процессом позже (см. man 2 madvise), но в обмен на это инструменты проверки памяти, такие как top, не будут сразу отражать освобождение в своём отображении резидентной памяти (столбец RSS): Только при недостатке памяти Linux фактически удалит освобождённые страницы из процесса и обновит свои статистические данные RSS. До этого страницы отображаются как LazyFree в /proc/PID/smaps (см. man 5 proc).

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

-xp

На 64-битных машинах, runtime-линковщик обычно должен отображать объектный код в нижние 2 Гб адресного пространства из-за x86_64 малой модели памяти, где большинство ссылок на символы являются 32-битными. Проблема в том, что эти 2 Гб адресного пространства могут заполниться, особенно если вы загружаете очень большое количество объектных файлов в GHCi.

Этот флаг предлагает обходной путь, хотя и несколько запутанный. Чтобы иметь возможность загрузить объектный файл за пределами нижних 2 Гб, объектный код необходимо скомпилировать с -fPIC -fexternal-dynamic-refs. Когда передан флаг +RTS -xp, линковщик предположит, что все объектные файлы были скомпилированы с -fPIC -fexternal-dynamic-refs, и загрузит их в любое место в адресном пространстве. Вам нужно позаботиться о том, чтобы все загруженные вами объектные файлы (включая все пакеты) были скомпилированы правильным образом. Если это не так для какого-либо объекта, линковщик, вероятно, завершится с сообщением об ошибке, когда проблема будет обнаружена.

На некоторых платформах, где PIC всегда используется, например, x86_64 MacOS X, этот флаг включён по умолчанию.

-xm ⟨address⟩

Предупреждение

Этот параметр предназначен только для решения проблем с выделением памяти. Не используйте его, если GHCi завершается сообщением, похожим на «failed to mmap() memory below 2Gb». Попробуйте перекомпилировать объекты с -fPIC -fexternal-dynamic-refs и использовать флаг -xp вместо этого. Если вам нужно использовать этот параметр, чтобы запустить GHCi на вашем компьютере, пожалуйста, отправьте ошибку.

На 64-битных машинах RTS необходимо выделять память в нижних 2 Гб адресного пространства. Поддержка этого на разных операционных системах неравномерная и иногда терпит неудачу. Этот параметр предназначен для того, чтобы дать RTS подсказку о том, где он должен быть способен выделять память в нижних 2 Гб адресного пространства. Например, +RTS -xm20000000 -RTS намекнёт, что RTS должен выделять память, начиная с отметки 0,5 Гб. По умолчанию используется встроенная поддержка ОС для выделения памяти в нижних 2 Гб, если она доступна (например, mmap с MAP_32BIT в Linux), или иначе -xm40000000.

-xq ⟨size⟩
Значение по умолчанию

100к

Этот параметр относится к лимитам выделения; для получения более подробной информации см. GHC.Conc.enableAllocationLimit. Когда поток достигает своего лимита выделения, RTS выбрасывает исключение в поток, и поток получает дополнительный квоту выделения, прежде чем исключение снова будет выброшено, идея заключается в том, чтобы поток мог выполнить свои обработчики исключений. -xq контролирует размер этого дополнительного квоты.

7.7.3. Параметры RTS для управления сборщиком мусора

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

--copying-gc
Значение по умолчанию

включено

С версии

8.10.2

Обратный

–nonmoving-gc

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

--nonmoving-gc
Значение по умолчанию

выключено

С версии

8.10.1

Обратный

–copying-gc

Включает параллельный сборщик мусора маркировки и подметания для сборщиков мусора старшего поколения. Как правило, GHC использует копирующий сборщик мусора, останавливающий мир, для всех поколений. Это может привести к длительным паузам во время выполнения во время основных сборок мусора. --nonmoving-gc включает использование параллельного сборщика мусора маркировки и подметания для сборок старшего поколения. При этой стратегии сбора мусора сборка мусора старшего поколения может выполняться параллельно с мутацией.

Обратите внимание, что --nonmoving-gc не может использоваться с -G1, profiling и -c.

-xn
Значение по умолчанию

выключено

С версии

8.10.1

Псевдоним для --nonmoving-gc

-A ⟨size⟩
Значение по умолчанию

1 МБ

Устанавливает размер области выделения, используемой сборщиком мусора. Область выделения (фактически генерация 0 шаг 0) фиксированная и никогда не изменяется в размере (если вы не используете -H [⟨size⟩], ниже).

Увеличение размера области выделения может или не может улучшить производительность (большая область выделения означает худшее поведение кэша, но меньше сборок мусора и меньше продвижения).

При наличии только 1 поколения (например, -G1, см. -G ⟨generations⟩) параметр -A задаёт минимальный размер области выделения, так как фактический размер области выделения будет изменён в соответствии с объёмом данных в куче (см. -F ⟨factor⟩, ниже).

-AL ⟨size⟩
Значение по умолчанию

значение -A

С версии

8.2.1

Устанавливает предел общего размера «больших объектов» (объектов больше, чем около 3 КБ), которые могут быть выделены до запуска GC. По умолчанию этот предел совпадает со значением -A.

Большие объекты не выделяются из обычной области выделения, установленной флагом -A, поэтому для них существует отдельный предел. Большие объекты, как правило, встречаются гораздо реже, чем маленькие объекты, поэтому большинство программ достигают предела -A раньше предела -AL. Однако предел -A является по-капабильностным, а предел -AL — глобальным, поэтому по мере увеличения -N становится более вероятным, что мы достигнем предела -AL раньше. Для компенсации этого может потребоваться использовать больший предел -AL при использовании большой -N.

Чтобы увидеть, эффективно ли вы используете всю память, зарезервированную для области выделения (-A раз -N), посмотрите вывод +RTS -S и проверьте, соответствует ли количество памяти, выделенной между сборками мусора, значению -A раз -N. Если нет, существуют два возможных решения: используйте -n для установки размера фрагмента яслей или используйте -AL для увеличения предела для больших объектов.

-O ⟨size⟩
Значение по умолчанию

1м

Установите минимальный размер старшего поколения. Старшее поколение собирается всякий раз, когда его размер достигает этого значения или значения параметра -F ⟨factor⟩, умноженного на размер живых данных на предыдущей основной сборке мусора, в зависимости от того, какое значение больше.

-n ⟨size⟩
По умолчанию

4МБ с -A16m или больше, иначе 0.

[Пример: -n4m ] Если задано ненулевое значение, этот параметр делит область выделения (значение -A ) на фрагменты указанного размера. Во время выполнения, когда процессор исчерпывает текущий фрагмент, ему предоставляется другой фрагмент из пула, пока пул не будет исчерпан, после чего запускается сборка мусора.

Этот параметр полезен только при параллельной работе (-N2 или больше). Он позволяет ядрам процессора эффективнее использовать доступную область выделения, даже когда ядра выделяют память с разной скоростью. Без -n, каждое ядро получает область выделения фиксированного размера, указанную параметром -A, и первое ядро, исчерпавшее свою область выделения, запускает сборку мусора на всех ядрах. Это может привести к сборке мусора, когда области выделения некоторых ядер заполнены только частично, поэтому цель параметра -n — позволить ядрам, которые выделяют память быстрее, получить больше области выделения. Это означает менее частые сборки мусора, что приводит к меньшей нагрузке от сборки мусора при том же размере кучи.

Это особенно полезно в сочетании с большими значениями -A , например -A64m -n4m является полезной комбинацией на больших количествах ядер (8+).

-c

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

Для данного размера кучи (с использованием параметра -H [⟨size⟩]) уплотнение может фактически уменьшить стоимость сборки мусора, позволив выполнять меньше сборок мусора. Это более вероятно, когда отношение живых данных к размеру кучи высокое, скажем, больше 30%.

Примечание

Уплотнение в настоящее время не работает, когда запрашивается одно поколение с использованием параметра -G1.

-c ⟨n⟩
По умолчанию

30

Автоматически включать уплотнение при сборе, когда живые данные превышают ⟨n⟩% от максимального размера кучи (см. параметр -M ⟨size⟩). Обратите внимание, что максимальный размер кучи по умолчанию не ограничен, поэтому этот параметр не имеет эффекта, если максимальный размер кучи не установлен с помощью -M ⟨size⟩.

-F ⟨factor⟩
По умолчанию

2

Этот параметр управляет объемом памяти, резервируемой для более старых поколений (и в случае коллектора с двумя пространствами размером области выделения) как коэффициент от объема живых данных. Например, если было 2 МБ живых данных в старейшем поколении, когда мы последний раз проводили сборку мусора, то по умолчанию мы будем ждать, пока она не вырастет до 4 МБ, прежде чем проводить сборку мусора снова.

По умолчанию, этот параметр работает хорошо. Если у вас много памяти, обычно лучше использовать -H ⟨size⟩ (см. -H [⟨size⟩]), чем увеличивать -F ⟨factor⟩.

Значение -F ⟨factor⟩ будет автоматически уменьшено сборщиком мусора, когда максимальный размер кучи (параметр -M ⟨size⟩) приближается к своему пределу.

-G ⟨generations⟩
По умолчанию

2

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

Указание 1 поколения с +RTS -G1 даёт вам простой коллектор с двумя пространствами, как вы ожидаете. В коллекторе с двумя пространствами параметр -A ⟨size⟩ задаёт минимальный размер области выделения, так как область выделения будет увеличиваться с количеством живых данных в куче. В многопоколенческом коллекторе область выделения имеет фиксированный размер (если вы не используете параметр -H [⟨size⟩]).

-qg ⟨gen⟩
По умолчанию

0

С

6.12.1

Использовать параллельную сборку мусора в поколении ⟨gen⟩ и выше. Опущение ⟨gen⟩ полностью отключает параллельную сборку мусора, возвращаясь к последовательной.

Параметры параллельной сборки мусора по умолчанию обычно подходят для параллельных программ (т.е. тех, использующих GHC.Conc.par, Стратегии или с несколькими потоками). Однако иногда полезно включить параллельную сборку мусора и для однопоточной последовательной программы, особенно если программа имеет большой объём данных в куче, и сборка мусора составляет значительную долю времени выполнения. Для использования параллельной сборки мусора в последовательной программе, включите параллельную среду выполнения с помощью подходящего параметра -N ⟨x⟩, и дополнительно может быть полезно ограничить параллельную сборку мусора старым поколением с -qg1.

-qb ⟨gen⟩
По умолчанию

1 для -A < 32МБ, иначе 0

С

6.12.1

Использовать балансировку нагрузки в параллельной сборке мусора в поколении ⟨gen⟩ и выше. Опущение ⟨gen⟩ полностью отключает балансировку нагрузки.

Балансировка нагрузки распределяет работу сборки мусора между доступными ядрами. Это хорошая идея, когда куча большая, и нам нужно распараллелить работу сборки мусора, однако это также неэффективно для коротких сборок молодого поколения в параллельной программе, потому что это может навредить локальности, перемещая данные из кэша процессора, где они используются, в кэш другого процессора. Поэтому по умолчанию балансировка нагрузки включена только для старого поколения. На самом деле, для параллельной программы иногда выгодно полностью отключить балансировку нагрузки с -qb.

-qn ⟨x⟩
По умолчанию

значение -N или количество ядер процессора, что меньше.

С

8.2.1

По умолчанию все возможности участвуют в параллельной сборке мусора. Однако, если мы хотим использовать очень большое значение -N , это может снизить производительность сборки мусора. По этой причине флаг -qn может использоваться для указания меньшего числа потоков, которые должны участвовать в сборке мусора. Во время сборки мусора, если активных рабочих больше, чем это число, некоторые из них будут спать в течение всего времени сборки мусора.

Флаг -qn может быть полезен при работе с большим значением -A (чтобы сборка мусора происходила реже) и большим значением -N (чтобы использовать гиперпотоки, например). Например, на 24-ядерной машине с 2 гиперпотоками на ядро, мы можем использовать -N48 -qn24 -A128m для указания, что мутатор должен использовать гиперпотоки, а сборщик мусора — только реальные ядра. Обратите внимание, что эта конфигурация будет использовать 6 ГБ для области выделения.

-H [⟨size⟩]
По умолчанию

0

Этот параметр предоставляет «предполагаемый размер кучи» для сборщика мусора. Думайте о -Hsize как о переменном параметре -A ⟨size⟩. Он говорит: я хочу использовать как минимум ⟨размер⟩ байтов, поэтому используйте оставшееся для увеличения значения -A.

Этот параметр не устанавливает предел для размера кучи: куча может расти за пределы данного размера как обычно.

Если ⟨размер⟩ опущен, то сборщик мусора примет размер кучи на момент предыдущей сборки мусора в качестве ⟨размер⟩. Это позволяет иметь большее значение -A , но без увеличения общих требований к памяти программы. Это может быть полезно, когда значение по умолчанию для небольшого -A является неоптимальным, например, в программах, которые создают большое количество долгоживущих данных.

-I ⟨seconds⟩
Значение по умолчанию

0,3 секунды в многопоточном режиме выполнения, 0 в однопоточном режиме

В многопоточных и SMP-версиях RTS (см. -threaded, Параметры, влияющие на компоновку), основная сборка мусора автоматически выполняется, если среда выполнения простаивает (нет вычислений Haskell). Время простоя, необходимое для запуска основной сборки мусора, задаётся параметром -I ⟨seconds⟩. Указание параметра -I0 отключает сборку мусора при простое.

Для интерактивного приложения, вероятно, рекомендуется использовать сборку мусора при простое, так как это позволит запускать финализаторы и обнаруживать зависшие потоки в период простоя, когда нет вычислений Haskell. Также это означает, что сборка мусора будет менее вероятна во время работы приложения, что может улучшить отзывчивость. Однако, если объём живых данных в куче особенно большой, то сборка мусора при простое может вызвать значительную задержку, а слишком короткий интервал может негативно повлиять на интерактивную отзывчивость.

Эта функция находится в стадии разработки, пожалуйста, сообщите нам, если она вызывает проблемы и/или требует дальнейшей настройки.

-Iw ⟨seconds⟩
Значение по умолчанию

0 секунд

По умолчанию, если сборка мусора при простое включена в многопоточном режиме выполнения, основная сборка мусора выполняется каждый раз, когда процесс простаивает достаточно долго (см. -I ⟨seconds⟩). Для крупных серверных процессов, принимающих регулярные, но редкие запросы (например, один раз в секунду), дорогостоящая основная сборка мусора может выполняться после каждого запроса. В качестве альтернативы полному отключению сборки мусора при простое (с помощью -I0), можно указать минимальное время ожидания между сборками мусора при простое с помощью этого флага. Например, -Iw60 гарантирует, что сборка мусора при простое выполняется не чаще, чем один раз в минуту.

Эта функция находится в стадии разработки, пожалуйста, сообщите нам, если она вызывает проблемы и/или требует дальнейшей настройки.

-ki ⟨size⟩
Значение по умолчанию

1k

Устанавливает начальный размер стека для новых потоков.

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

Примечание

Этот флаг раньше был просто -k, но был переименован в -ki в GHC 7.2.1. Старое имя всё ещё поддерживается для обратной совместимости, но может быть удалено в будущих версиях.

-kc ⟨size⟩
Значение по умолчанию

32k

Устанавливает размер фрагментов стека.

Когда текущий стек потока переполняется, создаётся новый фрагмент стека и добавляется к стеку потока до тех пор, пока не будет достигнут предел, заданный параметром -K ⟨size⟩.

Преимущества меньших фрагментов стека заключаются в том, что сборщик мусора может избежать обхода фрагментов стека, если известно, что они не изменялись с момента последней сборки, поэтому уменьшение размера фрагмента означает, что сборщик мусора может идентифицировать больше стека как неизменённый, и накладные расходы сборки мусора могут быть уменьшены. С другой стороны, слишком маленькие фрагменты стека добавляют некоторую нагрузку, так как будет больше переполнений/выполнений между фрагментами. Значение по умолчанию 32k, кажется, является разумным компромиссом в большинстве случаев.

-kb ⟨size⟩
Значение по умолчанию

1k

Устанавливает размер буфера фрагментов стека. Когда фрагмент стека переполняется и создаётся новый фрагмент стека, часть данных из предыдущего фрагмента стека перемещается в новый фрагмент, чтобы избежать непосредственного недолива и повторяющегося переполнения/недолива на границе. Объем перемещаемого стека задаётся параметром -kb.

Обратите внимание, что для экономии места это значение обычно должно быть меньше 10% от размера фрагмента стека (-kc ⟨size⟩), потому что в цепочке фрагментов стека каждый фрагмент будет иметь пробел неиспользуемого пространства такого размера.

-K ⟨size⟩
Значение по умолчанию

80% физической памяти

Устанавливает максимальный размер стека для отдельного потока в ⟨size⟩ байт. Если поток пытается превысить это ограничение, ему будет отправлено исключение StackOverflow. Ограничение можно полностью отключить, задав размер 0.

Этот параметр нужен в основном для того, чтобы предотвратить потребление всей доступной памяти в машине программой, попавшей в бесконечный цикл.

-m ⟨n⟩
Значение по умолчанию

3%

Минимальный процент ⟨n⟩ кучи, который должен быть доступен для выделения.

-M ⟨size⟩
Значение по умолчанию

неограниченно

Устанавливает максимальный размер кучи в ⟨size⟩ байт. Куча обычно увеличивается и уменьшается в соответствии с потребностями программы в памяти. Единственная причина наличия этого параметра заключается в том, чтобы предотвратить неограниченный рост кучи и заполнение всего доступного пространства подкачки, что, по меньшей мере, приведёт к тому, что программа будет суммарно убита операционной системой.

Максимальный размер кучи также влияет на другие параметры сборки мусора: когда количество живых данных в куче превышает определённую долю максимального размера кучи, уплотнение сборки будет автоматически включено для самой старой генерации, и параметр -F будет уменьшен, чтобы избежать превышения максимального размера кучи.

-Mgrace=⟨size⟩
Значение по умолчанию

1M

Если размер кучи программы превышает значение, установленное параметром -M ⟨size⟩, RTS выбрасывает исключение для программы, и программе предоставляется дополнительная квота выделения перед повторной генерацией исключения, с целью предоставления программе возможности выполнить свои обработчики исключений. -Mgrace= контролирует размер этой дополнительной квоты.

--numa
--numa=<mask>

Включает NUMA-осознанное выделение памяти в среде выполнения (доступно только с -threaded, и в настоящее время только на Linux и Windows).

Предыстория: некоторые системы имеют неравномерную архитектуру памяти, где основная память разделена на банки, которые «локальны» для определённых ядер процессора. Доступ к локальной памяти быстрее, чем доступ к удалённой памяти. Операционная система предоставляет API для выделения локальной памяти и привязки потоков к конкретным ядрам процессора, чтобы мы могли гарантировать, что определённые обращения к памяти используют локальную память.

Параметр --numa сообщает RTS настроить использование памяти для максимального использования локальной памяти. В частности, RTS будет:

  • Определять количество NUMA-узлов (N) путём запроса к ОС.
  • Управлять отдельными пулами памяти для каждого узла.
  • Сопоставлять возможности с NUMA-узлами. Возможность C сопоставляется с NUMA-узлом C mod N.
  • Привязывать потоки-работники к соответствующему узлу.
  • Выделять ясли из локальной памяти узла.
  • Выполнять другие выделения памяти, в том числе в GC, из локальной памяти узла.
  • При балансировке нагрузок отдавать предпочтение миграции потоков в другую возможность на том же узле.

Флаг --numa обычно выгоден, когда программа использует все ядра большой многоядерной NUMA-системы с большой областью выделения (-A). Все обращения к памяти в области выделения будут направляться в локальную память, что может значительно сократить число обращений к удалённой памяти. Типичное ускорение выполнения на уровне 10%, но может значительно отличаться в зависимости от аппаратного обеспечения и поведения программы в отношении памяти.

Обратите внимание, что RTS не устанавливает сродство процессора для привязанных потоков и потоков, входящих в Haskell из C/C++, поэтому если ваша программа использует привязанные потоки, вы должны убедиться, что каждый привязанный поток вызывает API RTS rts_setInCallCapability(c,1) из C/C++ перед вызовом в Haskell. В противном случае может возникнуть несоответствие между процессором, на котором выполняется поток, и памятью, которую он использует во время выполнения кода Haskell, что сведёт на нет любые преимущества от --numa.

Если задано явное значение <mask>, оно интерпретируется как битовая карта, указывающая NUMA-узлы, на которых следует запустить программу. Например, --numa=3 запустит программу на NUMA-узлах 0 и 1.

--long-gc-sync
--long-gc-sync=<seconds>

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

Длительная синхронизация GC может быть вызвана потоком мутатора, находящимся внутри вызова unsafe FFI или работающим в цикле, который не выделяет память и не уступает управление. Чтобы исправить первое, сделайте вызов safe, а чтобы исправить второе, либо избегайте вызова рассматриваемого кода, либо скомпилируйте его с помощью -fomit-yields.

По умолчанию этот флаг будет выводить предупреждение в stderr, когда время синхронизации превысит заданное значение. Однако это поведение можно переопределить: хук longGCSync() вызывается, когда время синхронизации превышено во время фазы синхронизации, а хук longGCSyncEnd() — в конце. Оба этих хука можно переопределить в RtsConfig при запуске среды выполнения с флагом hs_init_ghc(). Стандартные реализации этих хуков (LongGcSync() и LongGCSyncEnd() соответственно) выводят предупреждения в stderr.

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

Время синхронизации GC, а также другие статистические данные GC, доступны, вызвав функцию getRTSStats() из C или GHC.Stats.getRTSStats из Haskell.

7.7.4. Параметры RTS для получения статистических данных о времени выполнения

-T
-t [⟨file⟩]
-s [⟨file⟩]
-S [⟨file⟩]
--machine-readable
--internal-counters

Эти параметры генерируют статистические данные системы времени выполнения, такие как время, затраченное на выполнение программы и сборку мусора, количество выделенной памяти, максимальный размер кучи и так далее. Три варианта предоставляют разный уровень детализации: -T собирает данные, но не выводит их на экран; -t выводит одну строку вывода в том же формате, что и опция -Rghc-timing GHC; -s генерирует более подробный свод в конце программы; и -S дополнительно предоставляет информацию о каждом процессе сборки мусора. Передача --internal-counters многопоточной среде выполнения приведет к тому, что подробный свод будет включать различные внутренние счетчики, накопленные во время выполнения; обратите внимание, что они не определены и могут меняться между выпусками.

Вывод помещается в ⟨file⟩. Если ⟨file⟩ опущено, вывод направляется в stderr.

Если вы используете флаг -T, то доступ к статистике следует осуществлять с помощью GHC.Stats.

Если вы используете флаг -t, то по завершении программы вы увидите примерно следующее:

<<ghc: 36169392 bytes, 69 GCs, 603392/1065272 avg/max bytes residency (2 samples), 3M in use, 0.00 INIT (0.00 elapsed), 0.02 MUT (0.02 elapsed), 0.07 GC (0.07 elapsed) :ghc>>

Это указывает на:

  • Общее количество байт, выделенных программой за все время выполнения.
  • Общее количество выполненных сборок мусора.
  • Среднюю и максимальную «резиденцию», которая представляет собой количество активных данных в байтах. Система времени выполнения может определить количество активных данных только во время основной сборки мусора, поэтому количество образцов соответствует количеству основных сборок мусора (и обычно относительно невелико). Для получения более точного представления о профиле кучи вашей программы используйте опцию RTS -hT (Параметры RTS для профилирования).
  • Пиковое использование памяти, выделенной системой времени выполнения от операционной системы.
  • Время процессора и время выполнения программы при инициализации системы времени выполнения (INIT), выполнении самой программы (MUT, мутатор) и сборке мусора (GC).

Также вы можете получить эти данные в более совместимом с будущим формате, читаемом машиной, с помощью -t --machine-readable:

[("bytes allocated", "36169392")
,("num_GCs", "69")
,("average_bytes_used", "603392")
,("max_bytes_used", "1065272")
,("num_byte_usage_samples", "2")
,("peak_megabytes_allocated", "3")
,("init_cpu_seconds", "0.00")
,("init_wall_seconds", "0.00")
,("mutator_cpu_seconds", "0.02")
,("mutator_wall_seconds", "0.02")
,("GC_cpu_seconds", "0.07")
,("GC_wall_seconds", "0.07")
]

Если вы используете флаг -s, то по окончании выполнения программы вы увидите что-то вроде этого (точные детали будут зависеть от используемой системы времени выполнения, например, вы увидите данные профилирования только если ваша система времени выполнения скомпилирована с поддержкой профилирования):

    36,169,392 bytes allocated in the heap
     4,057,632 bytes copied during GC
     1,065,272 bytes maximum residency (2 sample(s))
        54,312 bytes maximum slop
             3 MB total memory in use (0 MB lost due to fragmentation)

Generation 0:    67 collections,     0 parallel,  0.04s,  0.03s elapsed
Generation 1:     2 collections,     0 parallel,  0.03s,  0.04s elapsed

SPARKS: 359207 (557 converted, 149591 pruned)

INIT  time    0.00s  (  0.00s elapsed)
MUT   time    0.01s  (  0.02s elapsed)
GC    time    0.07s  (  0.07s elapsed)
EXIT  time    0.00s  (  0.00s elapsed)
Total time    0.08s  (  0.09s elapsed)

%GC time      89.5%  (75.3% elapsed)

Alloc rate    4,520,608,923 bytes per MUT second

Productivity  10.5% of total user, 9.1% of total elapsed
  • «Байты, выделенные в куче», — это общее количество байтов, выделенных программой за все время выполнения.
  • По умолчанию GHC использует копирующий сборщик мусора. «Байты, скопированные во время сборки мусора», — это количество байтов, которое необходимо было скопировать во время сборки мусора.
  • Максимальное количество памяти, фактически используемой вашей программой, равно значению «Байты максимальной резиденции». Это проверяется только во время основных сборок мусора, поэтому это всего лишь приближение; количество образцов показывает, сколько раз это проверялось.
  • «Байты максимального проса», — это максимальное количество памяти, которая когда-либо терялась из-за способа выделения памяти GHC блоками. Прос — это память в конце блока, которая была потеряна. Управлять этим невозможно; мы просто хотим видеть, сколько памяти теряется таким образом.
  • «Общая используемая память» — это пиковое использование памяти, выделенной системой времени выполнения от операционной системы.
  • Далее следует информация о выполненных сборках мусора. Для каждой генерации указано, сколько сборок мусора было выполнено, сколько из них было выполнено параллельно, общее время процессора, затраченное на сборку мусора для этой генерации, и общее время выполнения программы во время сборки мусора для этой генерации.
  • Статистика SPARKS относится к использованию Control.Parallel.par и связанных функций в программе. Каждый всплеск представляет вызов par; всплеск «преобразуется», когда он выполняется параллельно; и всплеск «обрезается», когда обнаруживается, что он уже вычислен, и исключается из пула сборщиком мусора. Любые оставшиеся всплески удаляются по завершении выполнения, поэтому «преобразованные» плюс «обрезанные» не обязательно складываются в сумму.
  • Далее указано время процессора и время выполнения программы, разбитое по функциям системы времени выполнения в момент времени. INIT — это инициализация системы времени выполнения. MUT — это время мутатора, то есть время, затраченное на фактическое выполнение вашего кода. GC — это время, затраченное на сборку мусора. RP — время, затраченное на профилирование ссылок. PROF — время, затраченное на другие операции профилирования. EXIT — время завершения системы времени выполнения. И, наконец, Total, конечно, — это общее время.

    %GC time показывает, какой процент GC относится к Total. «Скорость выделения» показывает «байты, выделенные в куче», поделенные на время процессора MUT. «Производительность» показывает, какой процент общего времени процессора и времени выполнения затрачивается на мутатор (MUT).

Флаг -S, а также выводящий тот же результат, что и флаг -s, печатает информацию о каждой сборке мусора по мере её выполнения:

    Alloc    Copied     Live    GC    GC     TOT     TOT  Page Flts
    bytes     bytes     bytes  user  elap    user    elap
   528496     47728    141512  0.01  0.02    0.02    0.02    0    0  (Gen:  1)
[...]
   524944    175944   1726384  0.00  0.00    0.08    0.11    0    0  (Gen:  0)

Для каждой сборки мусора мы печатаем:

  • Сколько байтов было выделено в этой сборке мусора.
  • Сколько байтов было скопировано в этой сборке мусора.
  • Сколько байтов в настоящее время активно используется.
  • Сколько времени (время процессора и время выполнения) заняла эта сборка мусора.
  • Сколько времени работает программа (время процессора и время выполнения).
  • Сколько страниц было переобработано во время этой сборки мусора.
  • Сколько страниц было переобработано с момента завершения последней сборки мусора.
  • Какая генерация собирается мусор.

7.7.5. Параметры RTS для параллелизма и конкурености

Параметры RTS, относящиеся к конкурености, описаны в Использование Concurrent Haskell, а параметры для параллелизма — в Параметры RTS для SMP-параллелизма.

7.7.6. Параметры RTS для профилирования

Большинство параметров профилирования RTS доступны только при компиляции программы с поддержкой профилирования (см. Параметры компилятора для профилирования и Параметры RTS для профилирования кучи для параметров времени выполнения). Однако существует один параметр профилирования, доступный для обычных, не профилируемых исполняемых файлов:

-hT
-h

Генерирует базовый профиль кучи в файл prog.hp. Для создания графика профиля кучи используйте hp2ps (см. hp2ps — Рендеринг профилей кучи в PostScript). Базовый профиль кучи разбивается по конструкторам данных, а другие типы замыканий (функции, указатели и т. д.) группируются в общие категории (например, FUN, THUNK). Для получения более подробного профиля используйте полную поддержку профилирования (Профилирование). Может быть сокращён до -h.

Примечание

Значение сокращённого -h зависит от того, была ли ваша программа скомпилирована для профилирования. (См. Параметры RTS для профилирования кучи для получения более подробной информации.)

-L ⟨n⟩
Значение по умолчанию

25 символов

Устанавливает максимальную длину имён центров затрат, перечисленных в профиле кучи.

7.7.7. Отслеживание

Когда программа связана с опцией -eventlog (Параметры, влияющие на компоновку), события выполнения могут быть записаны несколькими способами:

  • В двоичном формате в файл для последующего анализа различными инструментами. Одним из таких инструментов является ThreadScope, который интерпретирует журнал событий, чтобы создать визуальный профиль параллельного выполнения программы.
  • В двоичном формате в настраиваемый записыватель журнала событий. Это позволяет проводить анализ событий в режиме реального времени во время выполнения программы.
  • В текстовом формате в стандартный вывод для отладки.
-l ⟨flags⟩

Записывать события в двоичном формате. Без указания ⟨flags⟩, это записывает набор событий по умолчанию, подходящий для использования с инструментами, такими как ThreadScope.

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

В некоторых специальных случаях вам может потребоваться больший контроль над тем, какие события включать. ⟨flags⟩ — это последовательность одного или нескольких символов, указывающих, какие классы событий необходимо записывать. В настоящее время это следующие классы событий, которые можно включить/отключить:

  • s — события планировщика, включая создание потоков Haskell и события начала/остановки. Включены по умолчанию.
  • g — события сборки мусора, включая начало/остановку сборки мусора. Включены по умолчанию.
  • n — события неперемещаемой сборки мусора (см. --nonmoving-gc) , включая начало и конец одновременной маркировки и подсчёта, для характеристики фрагментации кучи. Отключены по умолчанию.
  • p — параллельные искры (выборка). Включены по умолчанию.
  • f — параллельные искры (полная точность). Отключены по умолчанию.
  • u — пользовательские события. Это события, испускаемые кодом Haskell, используя функции, такие как Debug.Trace.traceEvent. Включены по умолчанию.

Вы можете отключить определённые классы или включить/отключить все классы сразу:

  • a — включить все классы событий, перечисленные выше
  • -⟨x⟩ — отключить данный класс событий для любого из перечисленных классов событий
  • -a — отключить все классы

Например, -l-ag отключит все классы событий (-a) за исключением событий сборки мусора (g).

Для событий искр существуют два режима: выборка и полная точность. Существует множество событий на каждом этапе жизненного цикла каждой искры, обычно это создание и запуск, но есть и некоторые более исключительные возможности. В режиме выборки количество появлений каждого типа события искры выборочно отсчитывается с высокой частотой. В режиме полной точности каждое событие искры записывается индивидуально. Последний режим имеет более высокую нагрузку на время выполнения и не включён по умолчанию.

Формат файла журнала описан в этом руководстве пользователя в Форматы кодирования журналов событий. Его можно анализировать в Haskell с помощью библиотеки ghc-events. Для вывода содержимого файла .eventlog в текстовом формате используйте инструмент ghc-events show, который поставляется с пакетом ghc-events.

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

-ol ⟨filename⟩
Значение по умолчанию

<program>.eventlog

С

8.8

Устанавливает место назначения для журнала событий, созданного флагом -l ⟨flags⟩.

-v [⟨flags⟩]

Записывать события в текстовом формате в стандартный вывод, вместо файла .eventlog. Флаги ⟨flags⟩ такие же, как для -l, с дополнительным параметром t, который указывает, что каждое выводимое событие должно предваряться значением отметки времени (в двоичном файле .eventlog все события автоматически связаны со временем).

Параметры отладки -Dx также генерируют события, которые регистрируются с помощью фреймворка отслеживания. По умолчанию эти события выводятся в текстовом формате в stdout (-Dx подразумевает -v), но их можно сохранить в двоичном файле журнала событий с помощью параметра -l.

7.7.8. Параметры RTS для хакеров, отладчиков и всех заинтересованных

Эти параметры RTS могут использоваться (а) для избежания ошибки GHC, (б) для просмотра того, «что происходит на самом деле», или (в) просто так. Не рекомендуется для повседневного использования!

-B

Прозвонить звонок в начале каждой (большой) сборки мусора.

Удивительно, но люди действительно используют этот параметр! Наш друг из Дарема (Англия), Пол Кэллахан, пишет: «Некоторые люди здесь используют его для различных целей—искренне!—например, подтверждение того, что код/машина что-то делает, обнаружение бесконечных циклов, оценка стоимости недавно добавленного кода. Определённые люди могут даже сказать, на каком этапе [программа] находится по шаблону звукового сигнала. Но основное использование — для раздражения других в одном офисе…»

-D ⟨x⟩

Флаг отладки RTS; доступен только, если программа была связана с параметром -debug. Различные значения ⟨x⟩ предоставляются для включения сообщений отладки и дополнительных проверок на корректность во время выполнения в различных подсистемах RTS, например, +RTS -Ds -RTS включает сообщения отладки из планировщика. Используйте +RTS -? для того, чтобы узнать, какие флаги отладки поддерживаются.

Полный список поддерживаемых флагов:

-Ds DEBUG: scheduler
-Di DEBUG: interpreter
-Dw DEBUG: weak
-DG DEBUG: gccafs
-Dg DEBUG: gc
-Db DEBUG: block
-DS DEBUG: sanity
-DZ DEBUG: zero freed memory on GC
-Dt DEBUG: stable
-Dp DEBUG: prof
-Da DEBUG: apply
-Dl DEBUG: linker
-Dm DEBUG: stm
-Dz DEBUG: stack squeezing
-Dc DEBUG: program coverage
-Dr DEBUG: sparks
-DC DEBUG: compact

Сообщения отладки будут отправлены в двоичный файл журнала событий вместо stdout, если добавлен параметр -l ⟨flags⟩. Это может быть полезно для уменьшения накладных расходов при отслеживании.

Чтобы понять, что они делают, наилучшим способом является поиск в каталоге rts/ в коде GHC макросов, таких как DEBUG(scheduler или DEBUG_scheduler.

-r ⟨file⟩

Создать статистику «тик-так» в конце выполнения программы (доступно только, если программа была связана с -debug). Работа с ⟨file⟩ такая же, как и в параметре RTS -S [⟨file⟩], выше.

Дополнительную информацию об отслеживании «тик-так» см. в Использование отслеживания «тик-так» (для разработчиков).

-xc

(Доступно только при компиляции программы для профилирования.) При возникновении исключения в программе этот параметр вызывает вывод стека вызовов в stderr.

Это может быть особенно полезно при отладке: если ваша программа жалуется на ошибку head [] и вы не знаете, какой фрагмент кода её вызывает, компиляция с -prof -fprof-auto (см. -prof) и выполнение с +RTS -xc -RTS покажет точный стек вызовов в момент возникновения ошибки.

Вывод содержит один отчёт для каждого возникшего исключения в программе (программа может вызывать и обрабатывать несколько исключений во время выполнения), где каждый отчёт выглядит примерно так:

*** Exception raised (reporting due to +RTS -xc), stack trace:
  GHC.List.CAF
  --> evaluated by: Main.polynomial.table_search,
  called from Main.polynomial.theta_index,
  called from Main.polynomial,
  called from Main.zonal_pressure,
  called from Main.make_pressure.p,
  called from Main.make_pressure,
  called from Main.compute_initial_state.p,
  called from Main.compute_initial_state,
  called from Main.CAF
  ...

Стек вызовов часто может начинаться с неинформативной части, например GHC.List.CAF; это артефакт оптимизатора GHC, который перемещает исключения в верхний уровень, где система профилирования назначает их в центр затрат «CAF». Однако +RTS -xc не просто выводит текущий стек, а просматривает глубже и сообщает о стеке на момент оценки CAF, и может сообщать о дополнительных стеках до тех пор, пока не будет найден не-CAF стек. В приведённом примере следующий стек (после --> evaluated by ) содержит много информации о том, что программа делала во время оценки head [].

Независимо от реализации, имена функций в стеке, надеемся, дадут вам достаточно подсказок для поиска ошибки.

См. также функцию traceStack в модуле Debug.Trace для другого способа просмотра стеков вызовов.

-Z

Выключить сжатие фреймов обновлений при переключении контекстов. (Нет особой причины для его выключения, кроме обеспечения точности определённых данных, собираемых относительно количества входов тханков.)

7.7.9. Получение информации о RTS

--info

Возможна запрос информации о RTS. Для этого используйте флаг --info, например:

$ ./a.out +RTS --info
[("GHC RTS", "YES")
,("GHC version", "6.7")
,("RTS way", "rts_p")
,("Host platform", "x86_64-unknown-linux")
,("Host architecture", "x86_64")
,("Host OS", "linux")
,("Host vendor", "unknown")
,("Build platform", "x86_64-unknown-linux")
,("Build architecture", "x86_64")
,("Build OS", "linux")
,("Build vendor", "unknown")
,("Target platform", "x86_64-unknown-linux")
,("Target architecture", "x86_64")
,("Target OS", "linux")
,("Target vendor", "unknown")
,("Word size", "64")
,("Compiler unregisterised", "NO")
,("Tables next to code", "YES")
,("Flag -with-rtsopts", "")
]

Информация отформатирована для чтения как данные типа [(String, String)]. В настоящее время доступны следующие поля:

GHC RTS

Связан ли данный программный модуль с GHC RTS? (всегда «ДА»).

GHC version

Версия GHC, использованная для компиляции программы.

RTS way

Вариант (способ) выполнения. Наиболее распространённые значения: rts_v (обычный), rts_thr (многопоточный, т. е. связан с использованием опции -threaded) и rts_p (профилирующий, т. е. связан с использованием опции -prof). Другие варианты включают debug (связан с использованием -debug) и dyn (RTS связан динамически, т. е. как общая библиотека, а не статически в исполняемый файл). Эти варианты могут комбинироваться, например, может быть rts_thr_debug_p.

Target platformTarget architectureTarget OSTarget vendor

Платформа, для которой компилируется программа.

Build platformBuild architectureBuild OSBuild vendor

Платформа, на которой была построена программа. (То есть, целевая платформа самого GHC). Обычно совпадает с целевой платформой. (Возможно отличается при кросс-компиляции.)

Host platformHost architectureHost OSHost vendor

Платформа, на которой был скомпилирован сам GHC. Как правило, совпадает с платформами сборки и целевой платформой.

Word size

Либо "32" или "64", отражающие разрядность целевой платформы.

Compiler unregistered

Была ли эта программа скомпилирована с использованием «несрегистрированной» версии GHC? (Т.е., версия GHC без платформоспецифических оптимизаций, обычно, потому что эта платформа в настоящее время не поддерживается.) Это значение обычно «нет», если вы не используете экспериментальную сборку GHC.

Tables next to code

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

Flag -with-rtsopts

Значение флага GHC -with-rtsopts=⟨opts⟩ во время компиляции/подключения.

© 2002–2007 The University Court of the University of Glasgow. All rights reserved.
Licensed under the Glasgow Haskell Compiler License.
https://downloads.haskell.org/~ghc/8.10.2/docs/html/users_guide/runtime_control.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API