F # как язык HPC - PullRequest
       34

F # как язык HPC

12 голосов
/ 04 ноября 2010

Я разрабатываю код решетки Больцмана (динамика жидкости), используя F #.Сейчас я тестирую код на сервере с 24 ядрами и 128 ГБ памяти.Код в основном состоит из одной главной рекурсивной функции для эволюции времени и внутри цикла System.Threading.Tasks.Parallel.For для итерации трехмерного пространственного пространства.Пространство 3D имеет размер 500x500x500, и один временной цикл занимает вечность:).

let rec timeIterate time =
  // Time consuming for loop
  System.Threading.Tasks.Parallel.For(...)

Я бы ожидал, что сервер будет использовать все 24 ядра, то есть будет использовать 100%.Что я наблюдаю, это что-то между 1% и 30% использования.

И мои вопросы:

  1. Является ли F # подходящим инструментом для вычислений HPC на таких серверах?
  2. Реально ли использовать до 100% ЦП для решения реальной проблемы?
  3. Что мне нужно сделать, чтобы получить высокую скорость?Все в одной большой параллели для цикла, поэтому я ожидаю, что это все, что я должен делать ...
  4. Если F # НЕ подходящий язык, то какой язык?

Спасибо за любые предложения.

РЕДАКТИРОВАТЬ: Я готов поделиться кодом, если кто-то заинтересован взглянуть на него.

РЕДАКТИРОВАТЬ2: Вот урезанная версия кода: http://dl.dropbox.com/u/4571/LBM.zip Это не делает ничего разумного, и я надеюсь, что я не внес каких-либо ошибок, убрав код:)

Файл запуска - ShearFlow.fs, а в нижней части файла -

let rec mainLoop (fA: FArrayO) (mR: MacroResult) time =
  let a = LBM.Lbm.lbm lt pA getViscosity force g (fA, mR)

Ответы [ 7 ]

5 голосов
/ 04 ноября 2010

1.Является ли F # подходящим инструментом для вычислений HPC на таких серверах?

Это (F #), как язык, может поощрять код, который хорошо работает параллельно - по крайней мере, частьэто сокращение изменчивости состояния и функций высшего порядка - это может , а не будет .Однако с помощью HPC существует множество специализированных языков программирования / компиляторов и / или способов распределения нагрузки (например, совместно используемая единая память или распределенные микроядра).F # - это просто язык программирования общего назначения: он может иметь или не иметь доступ (например, привязки могут существовать или не существовать) к различным методам.(Это относится даже к нераспределенным параллельным вычислениям.)

2.Реально ли использовать до 100% ЦП для решения реальной проблемы?

Это зависит от того, что является ограничивающим фактором.В разговоре с моим другом, который занимается 5k + 100k + ядром исследований и разработок HPC, обмен данных и время простоя обычно являются ограничивающим фактором (конечно, этонамного большее n :-) и поэтому даже небольшие улучшения в IO (эффективность или другой алгоритм) могут привести к значительному выигрышу.Не забывайте о стоимости простого перемещения данных между процессорами / кэшами на одной машине!И, конечно же, постоянно медленный дисковый ввод-вывод ...

3.Что я должен сделать, чтобы получить высокую скорость?Все в одной большой параллели для цикла, поэтому я ожидаю, что это все, что я должен делать ...

Узнайте, где медленная часть (и), и исправьте ее (их).) :-) Например, запустить анализ профиля.Имейте в виду, что это может потребовать использования совершенно другого алгоритма или подхода.

4.Если F # НЕ является подходящим языком, то что это за язык?

Хотя я и не спорю об этом, мой докторский друг использует / работает над Charm ++ : это очень сфокусированный языкдля распределенных параллельных вычислений (не рассматриваемая среда, но я пытаюсь подчеркнуть :-) - F # пытается быть достойным языком общего назначения.

4 голосов
/ 04 ноября 2010

F # должно быть так же хорошо, как и любой язык.То, как вы пишете свой код, больше, чем сам язык, который определяет производительность.

Вы должны быть в состоянии приблизиться к 100%, по крайней мере, в верхнем диапазоне 90%, если ваши вычисления связаны с ЦП.

Может быть несколько причин, по которым вы не получаете 100% CPU здесь.

  1. Ваши вычисления могут быть связаны с вводом / выводом (выполняете ли вы файловые или сетевые операции в цикле for?)
  2. У вас есть проблемы с синхронизацией, например, большая блокировка (есть ли у вас общее состояние между потоками, включая то, где вы «фиксируете» результат?)
3 голосов
/ 04 ноября 2010

Является ли F # подходящим инструментом для вычислений высокопроизводительных вычислений на таких серверах?

Я не очень хорошо знаю F #, но скорее подозреваю, что это вполне хорошо подходит.В нем есть все нужные инструменты, и это функциональный язык, позволяющий выполнять высокопараллельное выполнение.

Реально ли использовать до 100% ЦП для реальной проблемы?

Да, или почти совсем.Но на самом деле ваше приложение должно использовать 2400% мощности процессора, если у вас 24 ядра!По крайней мере, так оно обычно и отображается.Если вы наблюдаете 30% использования, скорее всего, он работает на одном ядре и даже не использует его.

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

Ну, вы не показали свой код.Я могу только предположить, что что-то в вашем коде препятствует его параллельному выполнению.

В качестве альтернативы (использование процессора от 1% до 30% указывает на это), ваша проблема на самом деле не связана с вычислениями, и вычислениявсе время жду других ресурсов, таких как вторичная память.Это не обязательно зависит от проблемы - в конце концов, динамика жидкости - это проблема, связанная с вычислениями!- а точнее на вашей конкретной реализации.Пока что многое указывает на конфликт ресурсов.

2 голосов
/ 04 ноября 2010
  1. Я не думаю, что F # все же вошел в мейнстрим HPC, где доминируют Fortran, C и C ++, но я не вижу особых причин, по которым вам следует этого избегать.

  2. Нет, это не так, не в течение длительного периода времени. Рано или поздно все (сомнительное утверждение, что) коды HPC становятся ограниченными по пропускной способности памяти - ЦП могут обрабатывать числа намного быстрее, чем ОЗУ может загружать и хранить. При длительных вычислениях у вас хорошо получается использовать 10% от теоретического максимального количества FLOP, которые могут выполнять ваши процессоры.

  3. Я не достаточно хорошо знаю F #, чтобы давать конкретные рекомендации для вашей конфигурации (я один из тех программистов HPC на Fortran). Но в целом вам необходимо обеспечить хорошую балансировку нагрузки (т. Е. Все ядра выполняют одинаковый объем работы), эффективное и действенное использование иерархии памяти (что становится затруднительным, поскольку языки получают «более высокий уровень», поскольку они, как правило, затрудняют это управлять процессами на низком уровне), и лучшее, что вы можете сделать, это выбрать лучший алгоритм. Лучший параллельный алгоритм не обязательно является лучшим последовательным алгоритмом, выполненным параллельно, и я подозреваю, что лучший функциональный (реализация) алгоритма, возможно, не является лучшим (обязательной реализацией) алгоритма.

  4. Fortran.

1 голос
/ 05 ноября 2010

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

В настоящее время люди склонны считать FP серебряной пулей для всего параллельного, включая высокопроизводительные вычисления. NO. В противном случае вы увидите много работ FP, опубликованных на высокопроизводительных конференциях. На самом деле довольно мало.

Сейчас вы используете библиотеку Task Parallel, которая является библиотекой .Net для C # / F # / VB. Не специфично для F #. Который сам написан на C #, я считаю.

Имея это в виду, давайте вернемся к вашему вопросу. Почему вы не можете использовать 100% процессор? Навыки помогут вам найти узкое место, имеющие меньшее отношение к F #. Выполните профилирование вашей программы, посмотрите, ожидают ли некоторые потоки завершения других (чтобы продолжить, вам нужно завершить все вычисления в Paralle.For).

1 голос
/ 04 ноября 2010

Пул потоков имеет максимальное количество потоков в зависимости от различных обстоятельств.

С MSDN :

Максимальное количество потоков пула потоков

Количество операций, которые могут быть поставлены в очередь в пуле потоков, ограничено только доступной> памятью; однако пул потоков ограничивает количество потоков, которые могут быть активны в процессе одновременно. Начиная с версии .NET Framework 4, размер пула потоков для процесса по умолчанию зависит от нескольких факторов, таких как размер виртуального адресного> пространства. Процесс может вызвать метод GetMaxThreads, чтобы определить количество потоков.

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

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

Опять от MSDN :

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

При достижении минимума пул потоков может создавать дополнительные потоки или ждать завершения некоторых задач. Начиная с .NET Framework 4, пул потоков создает и уничтожает рабочие потоки с целью оптимизации пропускной способности, которая определяется как количество задач, выполняемых за единицу времени. Слишком мало потоков может не оптимально использовать доступные ресурсы, тогда как слишком много потоков может привести к конфликту ресурсов.

0 голосов
/ 04 ноября 2010

Вы пытались использовать инструменты анализа потоков, включенные в Visual Studio: с помощью опции профилировщика параллелизма в мастере производительности?

...