Я хочу разработать параллельное программное обеспечение для научных вычислений с нуля. Я хочу несколько мыслей, на каком языке начать. Программа включает в себя чтение / запись данных в текстовые файлы и параллельное выполнение тяжелых вычислений со многими факторизациями LU и использованием разреженных линейных решателей. Возможные решения, о которых я думал, это Fortran 2003/2008 с OpenMP или совмещенным массивом, C ++ с openmp cilk + или TBB, python. Любые другие, документированные, предложения приветствуются! Я очень хорошо знаю C, Fortran и Java (в таком порядке). Я сделал несколько сценариев на Python, но основные вещи.
Я знаю, что фортран очень быстр, но его трудно поддерживать и распараллеливать. Говорят, что C ++ медленный, если вы не используете внешние библиотеки и т. Д. Python, который мне нравится, но реалистично ли писать полнофункциональное программное обеспечение промышленного уровня?
Программное обеспечение должно уметь обрабатывать большие объемы данных и быть эффективным в научных вычислениях. Производительность имеет существенное значение.
Для справки, у меня уже есть работающее программное обеспечение, написанное на Фортране. Многие люди были вовлечены в разработку на протяжении многих лет, и код действительно грязный. Ведение и распараллеливание кода оказалось кошмаром, и я думаю об альтернативах.
Петрос
Ответы:
Позвольте мне попробовать и разбить ваши требования:
Из этого списка я бы рассмотрел следующие языки:
C, C ++, Фортран, Python, MATLAB, Java
Джулия - новый многообещающий язык, но сообщество все еще формируется вокруг него, и оно не было развернуто ни в каких новых важных кодах.
Чтение / запись текстовых данных
Это легко получить право на любом языке программирования. Убедитесь, что вы должным образом буферизируете и объединяете свой доступ ввода / вывода, и вы получите хорошую производительность на любом из языков, которые вам следует рассмотреть. Избегайте потоковых объектов в C ++, если вы не знаете, как использовать их эффективно.
Сильные интерфейсы / возможности для факторизации LU
Если вы выполняете плотную факторизацию LU, вы захотите использовать LAPACK или ScaLAPACK / Elemental для параллельной функциональности. LAPACK и ScaLAPACK написаны на Фортране, Elemental написан на C ++. Все три библиотеки эффективны, хорошо поддерживаются и документированы. Вы можете взаимодействовать с ними на любом из языков, которые вы должны рассмотреть.
Разреженные линейные решатели
Первичные свободно доступные разреженные линейные решатели почти все доступны через PETSc , написанный на C, который хорошо документирован и поддерживается. Вы можете взаимодействовать с PETSc на любом из языков, которые вы должны рассмотреть.
Производительность и масштабируемость для больших данных
Единственные парадигмы параллельного программирования, о которых вы упомянули, основаны на разделяемой памяти, что означает, что вы не рассматриваете основанный на MPI (передача сообщений) подход к распределенной памяти. По моему опыту, с помощью решения с распределенной памятью гораздо проще писать код, который масштабируется гораздо дальше десятка ядер. В наши дни почти все университетские «кластеры» основаны на MPI, большие машины с общей памятью дороги и, соответственно, редки. Вы должны рассмотреть MPI для вашего подхода, но мой совет будет применяться независимо от выбранной вами парадигмы программирования.
Что касается производительности на узле, если вы сами пишете числовые подпрограммы, проще всего добиться хорошей производительности последовательного интерфейса в Fortran. Если у вас есть небольшой опыт работы с C, C ++ или Python, вы можете получить очень сопоставимую производительность (C и C ++ не имеют себе равных, даже если Fortran, Python и MATLAB занимают около 25% времени без особых усилий). MATLAB делает это с помощью JIT-компилятора и очень хорошей выразительности линейной алгебры. Скорее всего, вам потребуется использовать Cython, numpy, Numberxpr или встраивать числовые ядра, чтобы получить заявленную производительность от Python. Я не могу комментировать производительность Java, потому что я не очень хорошо знаю язык, но подозреваю, что он не так уж далек от Python, если он написан экспертом.
Примечание по интерфейсам
Я надеюсь, что убедил вас, что вы сможете делать все, что хотите, на любом из языков программирования, которые вы рассматриваете. Если вы используете Java, интерфейсы C будут немного сложными. Python имеет превосходную поддержку интерфейса C и Fortran через ctypes, Cython и f2py. LAPACK уже упакован и доступен через scipy. MATLAB обладает всеми необходимыми функциями в своих собственных библиотеках, но его нелегко масштабировать или особенно легко запускать в кластерах. Java может поддерживать интерфейсы C и Fortran с JNI , но обычно не встречается в кластерах и в параллельном программном обеспечении для научных вычислений.
Ремонтопригодность
Многое из этого придет к личному вкусу, но общее согласие в отношении удобства обслуживания заключается в том, что вы хотите минимизировать количество строк кода в своем программном обеспечении, писать модульный код с четко определенными интерфейсами, а для вычислительного программного обеспечения обеспечить тесты, которые проверяют правильность и функциональность реализации.
Рекомендация
Мне лично очень повезло с Python, и я рекомендую его для многих вычислительных проектов. Я думаю, что вы должны строго рассмотреть это для вашего проекта. Python и MATLAB, вероятно, являются наиболее выразительными из языков, доступных для научных вычислений. Вы можете легко связать Python с любым другим языком программирования, вы можете использовать f2py, чтобы обернуть вашу текущую реализацию на Фортране и пошагово переписать те части, которые вы пожелаете в Python, проверяя, поддерживаете ли вы функциональность. В настоящее время я бы порекомендовал сочетание официальной реализации Python 2.7 с scipy . Вы можете легко начать работу с этим стеком из свободно распространяемого дистрибутива Python Enthought .
Вы также можете сделать большую часть этого в C, C ++ или Fortran. C и C ++ являются очень привлекательными языками для профессиональных разработчиков с большим опытом, но часто путают новых разработчиков и в этом смысле, вероятно, не являются хорошей идеей для более академического кода. Fortran и MATLAB популярны в академических вычислениях, но слабы в продвинутых структурах данных и выразительности, которые предлагает Python (например, вспомним объект dict Python).
Смежные вопросы:
источник
В дополнение к очень полному ответу Арона, я бы взглянул на различные темы в scicomp.stackexchange, которые касались вопроса о том, какой язык программирования выбрать - как относительно скорости программ, так и вопроса о том, насколько легко или сложно это писать и поддерживать программное обеспечение на этих языках.
Тем не менее, в дополнение к тому, что там было написано, позвольте мне сделать несколько замечаний:
(i) Вы включаете в свой список совместный массив Fortran. Насколько мне известно, количество компиляторов, которые на самом деле его поддерживают, очень мало - и мой, по сути, будет нулевым. Наиболее широко доступным компилятором Fortran является GNU gfortran, и хотя текущие источники разработки анализируют подмножество совместных массивов, я считаю, что он фактически не поддерживает ни один из них (т. Е. Он принимает синтаксис, но не реализует ни одну из семантик) , Это, конечно, общее замечание о новых стандартах Fortran: отставание, с которым компиляторы фактически поддерживают новые стандарты, измеряется через несколько лет - компиляторы только полностью внедрили Fortran 2003 за последние пару лет и только частично поддерживают Fortran 2008. Это не должно мешать вам использовать что-либо из этого, если у вас есть компилятор, который поддерживает то, что вы используете,
(ii) То же самое верно и в отношении C ++ / Cilk +: да, Intel разрабатывает это в ответвлении GCC, но оно недоступно ни в одном из выпусков GCC и, вероятно, не будет в течение некоторого времени. Вы можете ожидать, что это займет еще как минимум 2-3 года, пока вы не найдете Cilk + с версиями GCC, установленными на типичных машинах Linux.
(iii) C ++ / TBB - это отдельная история: TBB существует довольно давно, имеет очень стабильный интерфейс и совместим с большинством любых компиляторов C ++, которые существовали в течение последних нескольких лет (как в Linux, так и в Windows). , Мы использовали его в сделке. II уже несколько лет с хорошими результатами. Там также есть очень хорошая книга.
(iv) У меня есть собственное мнение об OpenMP, а именно, что это решение в поисках проблемы. Он хорошо работает для распараллеливания внутренних циклов, что может представлять интерес, если у вас очень регулярные структуры данных. Но это редко, что вы хотите сделать, если вам нужно что-то распараллелить - потому что вы действительно хотите распараллелить внешние циклы. И для этого такие решения, как TBB, являются намного лучшими решениями, потому что они используют механизмы языка программирования, а не пытаются описать то, что происходит вне языка (через #pragmas), и таким образом, что у вас нет доступа к дескрипторам потоков. , индикаторы состояния результата и т. д. изнутри вашей программы.
(v) Если вы экспериментируете, вы также можете взглянуть на новые языки программирования, разработанные для параллельного программирования и, в частности, для задач, подобных тем, которые вы описываете. По сути, есть два, на которые я бы посмотрел: X10 и Chapel . Я видел хорошие учебные пособия по часовне, и они, кажется, хорошо разработаны, хотя сегодня оба, конечно, также являются замкнутыми решениями.
источник
В общем, если вы действительно серьезно относитесь к этому программному проекту, я бы предложил полностью переписать на любом языке, который вам удобнее всего. Похоже, вы будете выполнять работу в одиночку, и, следовательно, вы получите лучшие результаты на языке, с которым вы чувствуете себя как дома.
Более конкретно, хотя, что касается параллелизма, я бы посоветовал вам попытаться немного нестандартно мыслить. У OpenMP есть свои сильные стороны, но он застрял в том, чтобы взять последовательный код и использовать параллелизм здесь и там. То же самое, по сути, для Intel TBB.
Cilk - это определенно шаг в правильном направлении, то есть он заставляет вас переосмыслить свою проблему / решение в изначально параллельной установке. Что мне не нравится в этом, так это то, что это еще один язык . Кроме того, поскольку он может лишь приблизительно вывести отношения между параллельными задачами, планировщик может быть достаточно консервативным и может плохо масштабироваться для определенных задач.
Хорошая новость заключается в том, что, опять же, если вы серьезно относитесь к своей реализации, вы можете делать то, что делает Cilk, например, переписывать вашу задачу как набор взаимозависимых задач и распределять их по нескольким процессорам / ядра, все по своему усмотрению, либо используя pthreads, либо неправильно используя OpenMP для порождения процессов. Хорошим примером того, как это можно сделать, является планировщик QUARK, используемый в библиотеке PLASMA . Хорошее сравнение его производительности против Cilk дано здесь .
источник
pthreads-win32
или внутриcygwin
проекта.Там было небольшое обсуждение Coarray Fortran в вышеупомянутых комментариях. В настоящее время, насколько мне известно, поддержка coarray в компиляторах примерно такая:
Вообще, я был бы осторожен, если бы начал код на основе coarray. Синтаксис прост и намного удобнее, чем Fortran / C / C ++ с MPI, но, тем не менее, он не такой полнофункциональный. Например, MPI поддерживает множество операций сокращения и т. Д., Что может быть очень удобно для вас. Это действительно зависит от вашей потребности в общении. Если вы хотите пример, дайте мне знать, и я могу предоставить вам несколько, если я могу выкопать файлы.
источник
Взгляните на Spark - это распределенная среда для вычислений в памяти, которая использует преимущества функционального программирования. Структура программы в Spark сильно отличается по сравнению с MPI, в основном вы пишете такой же код, как для одного компьютера, который автоматически распределяется как функции для данных, находящихся в памяти. Он поддерживает Scala, Java и Python.
Логистическая регрессия (scala):
Существует расширение под названием MLib (библиотека машинного обучения), которое использует библиотеку Fortran для некоторых низкоуровневых вычислений (я думаю, для Python используется numpy). Итак, идея проста: сконцентрируйтесь на своем алгоритме и оставьте оптимизации на более низких уровнях (порядок обработки, распределение данных и т. Д.).
источник