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

F # как язык HPC

Я разрабатываю код Lattice Boltzmann (Fluid dynamic), используя 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% использования.

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

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

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

EDIT: Я готов поделиться кодом, если кто-то заинтересован взглянуть на него.

EDIT2: Вот разделенная версия кода: 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)
4b9b3361

Ответ 1

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

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

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

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

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

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

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

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

Ответ 2

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

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

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

  • Ваши вычисления могут быть связаны с вводом-выводом (выполняете ли вы файловые или сетевые операции в цикле for?)
  • У вас есть проблемы с синхронизацией, такие как блокировка (у вас есть общее состояние между потоками, в том числе, где вы "совершаете" результат?)

Ответ 3

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

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

Насколько реалистично использовать до 100% процессора для реальной проблемы?

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

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

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

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

Ответ 4

  • Я не думаю, что F # еще попал в основное русло HPC, где доминируют Fortran, C и С++, но я не вижу особых причин, почему вы должны его избегать.

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

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

  • Fortran.

Ответ 5

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

Из MSDN:

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

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

Вы можете контролировать максимальное количество потоков с помощью методов GetMaxThreads и SetMaxThreads.

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

Опять же, из MSDN:

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

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

Ответ 6

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

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

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

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

Ответ 7

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