Spec-Zone.ru › Haskell 8

7.4. Использование Concurrent Haskell

GHC поддерживает Concurrent Haskell по умолчанию, без необходимости в специальных опциях или библиотек, скомпилированных определенным способом. Для доступа к библиотекам поддержки Concurrent Haskell, просто импортируйте Control.Concurrent. Более подробная информация о Concurrent Haskell представлена в документации к этому модулю.

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

  • Это позволяет использовать -N ⟨x⟩, что позволяет потокам работать параллельно на многопроцессорной или многоядерной машине. См. Использование SMP-параллелизма.
  • Если поток выполняет вызов внешней функции (и вызов не помечен unsafe), то другие Haskell-потоки в программе продолжат работу, пока вызов внешней функции выполняется. Кроме того, foreign export Haskell-функции могут быть вызваны из нескольких потоков ОС одновременно. См. Многопоточность и FFI.

Следующие опции RTS влияют на поведение Concurrent Haskell программ:

-C ⟨s⟩
Значение по умолчанию

20 миллисекунд

Устанавливает интервал переключения контекста на ⟨s⟩ секунд. Переключение контекста произойдёт в следующий момент выделения блока памяти, после истечения таймера (выделение блока памяти происходит каждые 4 килобайта выделения). С -C0 или -C, переключения контекста будут происходить как можно чаще (на каждом выделении блока памяти).

7.5. Использование SMP-параллелизма

GHC поддерживает выполнение Haskell программ параллельно на SMP (симметричном многопроцессорном) устройстве.

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

Однако эти два понятия тесно связаны. Использование нескольких процессоров позволяет выполнять конкурентные потоки параллельно, и именно это делает GHC's SMP-параллелизм. Но также возможно получить повышение производительности с параллелизмом в программах, не использующих конкурентность. Этот раздел описывает, как использовать GHC для компиляции и запуска параллельных программ, в Конкурентном и Параллельном Haskell мы опишем языковые особенности, влияющие на параллелизм.

7.5.1. Опции компиляции для SMP-параллелизма

Для использования нескольких процессоров ваша программа должна быть связана с опцией -threaded (см. Опции, влияющие на компоновку). Кроме того, следующие опции компилятора влияют на параллелизм:

-feager-blackholing

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

Опция -feager-blackholing заставляет каждый туннель пометить как находящийся в процессе оценки, как только начинается оценка. По умолчанию используется «ленивый блэкхолинг», где туннели помечаются как находящиеся в процессе оценки только тогда, когда поток приостанавливается по какой-либо причине. Ленивый блэкхолинг обычно более эффективен (на 1-2% или около того), потому что большинство туннелей не нуждаются в блэкхолинге. Однако жадный блэкхолинг может предотвратить большее повторное вычисление в параллельной программе, и это часто оказывается важным для параллелизма.

Мы рекомендуем компилировать любой код, предназначенный для выполнения в параллельном режиме, с флагом -feager-blackholing.

7.5.2. Опции RTS для SMP-параллелизма

Есть два способа запуска программы на нескольких процессорах: вызовите Control.Concurrent.setNumCapabilities из вашей программы или используйте опции RTS -N ⟨x⟩.

-N ⟨x⟩
-maxN ⟨x⟩

Используйте ⟨x⟩ одновременных потоков при запуске программы.

Выполняющая среда управляет набором виртуальных процессоров, которые мы называем возможностями, число которых определяется опцией -N. Каждая возможность может запускать один Haskell-поток за раз, поэтому количество возможностей равно количеству Haskell-потоков, которые могут выполняться физически параллельно. Возможность активируется одним или несколькими потоками ОС; выполняющая среда управляет пулом потоков ОС для каждой возможности, так что если Haskell-поток делает вызов внешней функции (см. Многопоточность и FFI), другой поток ОС может занять эту возможность.

Обычно ⟨x⟩ следует выбирать, чтобы соответствовать количеству процессорных ядер на машине 1. Например, на двухъядерной машине мы, вероятно, будем использовать +RTS -N2 -RTS.

Опущение ⟨x⟩, т.е. +RTS -N -RTS, позволяет выполняющей среде самостоятельно выбирать значение ⟨x⟩, основываясь на количестве процессоров на вашей машине.

Полное отсутствие -N⟨x⟩ означает -N1.

С -maxN⟨x⟩, т.е. +RTS -maxN3 -RTS, выполняющая среда выберет не более (x), также ограниченного количеством процессоров в системе. Опущение (x) — ошибка; если вам нужен по умолчанию, используйте -N.

Будьте осторожны, когда используете все процессоры своей машины: если некоторые из ваших процессоров заняты другими программами, это может на самом деле навредить производительности, а не улучшить её. Запрос GHC создать больше возможностей, чем у вас физических потоков, почти всегда плохая идея.

Установка -N также приводит к включению параллельного сборщика мусора (см. Опции RTS для управления сборщиком мусора).

Текущее значение опции -N доступно Haskell-программе через Control.Concurrent.getNumCapabilities, и его можно изменить во время выполнения программы, вызвав Control.Concurrent.setNumCapabilities.

Следующие опции влияют на способ планирования потоков выполняющей средой на процессорах:

-qa

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

Когда эта опция включена, потоки ОС для возможности \(i\) привязаны к процессорному ядру \(i\) с помощью API, предоставленного ОС для установки родственной связи потоков. Например, в Linux GHC использует sched_setaffinity().

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

-qm

Отключить автоматическую миграцию для балансировки нагрузки. Обычно выполняющая среда автоматически будет пытаться планировать потоки по доступным процессорам, чтобы использовать неиспользуемые процессоры; эта опция отключает это поведение. Обратите внимание, что миграция относится только к потокам; искры, созданные par , балансируются отдельно с помощью кражи работы.

Эта опция, вероятно, полезна только для конкурентных программ, которые явно планируют потоки на процессоры с помощью Control.Concurrent.forkOn.

7.5.3. Рекомендации по использованию SMP-параллелизма

Добавьте опцию RTS -s [⟨file⟩] при запуске программы, чтобы увидеть статистику времени, которая поможет вам определить, ускорила ли ваша программа работу, используя больше процессоров. Если пользовательское время больше, чем время выполнения, значит программа использовала более одного процессора. Вы также должны запустить программу без -N ⟨x⟩ для сравнения.

Вывод +RTS -s указывает, сколько «искр» было создано и выполнено во время работы программы (см. Опции RTS для управления сборщиком мусора), что даст вам представление о том, насколько хорошо работают ваши par аннотации.

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

1

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

© 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/using-concurrent.html

Spec-Zone.ru

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