Паралельна наукова комп'ютерна мова для розробки програмного забезпечення?


18

Я хочу розробити паралельно наукове програмне забезпечення для обчислень. Я хочу подумати, з якої мови почати. Програма передбачає читання / запис даних у файли txt і паралельні великі обчислення, з багатьма LU-факторизаціями та використанням розріджених лінійних розв'язувачів. Кандидатські рішення, про які я думав, - це Fortran 2003/2008 з OpenMP або спільним масивом, C ++ з openmp cilk + або TBB, python. Будь-які інші, задокументовані, пропозиції вітаються! Я дуже добре знаю C, Fortran та Java (у такому порядку). Я зробив деякі сценарії в python, але основні речі.

Я знаю, що Фортран дуже швидкий, але важко підтримувати і паралелізувати. Кажуть, що C ++ є повільним, якщо ви не використовуєте зовнішні бібліотеки тощо. Мені подобається Python, але чи реально написати повне масштабне програмне забезпечення промислового рівня?

Програмне забезпечення повинне вміти обробляти великі обсяги даних та бути ефективним у наукових обчисленнях. Виступ є сутнісним.

З іншого боку, у мене вже є робоче програмне забезпечення, написане на Fortran. Багато людей брали участь у розробці протягом багатьох років, і код дійсно брудний. Підтримка та паралелізація коду виявилася кошмаром, і я думаю про альтернативи.

Петрос


5
Як підморг C ++, я б не назвав Фортран важким для обслуговування. Обслугованість пов'язана з передовою практикою здебільшого, а не з вибору мови. Повільність C ++ перепродана. Також я рекомендую вам доповнити цю публікацію, щоб описати розмір даних та вимоги часу виконання. Я бачив, що "великий" змінюється на 9 або 10 порядків залежно від того, з ким я говорю.
Білл Барт

@BillBarth Проблема існуючого коду Fortran полягає в тому, що троє людей були залучені, використовуючи різні практики. Я родом зі С, один хлопець з F77 та інший хлопець з Matlab. Дані не підлягають розподілу та розміру для найбільшої за розмірами системи (я брав участь останнім часом). Код зміг імітувати систему з диференціальними рівняннями 72000 та алгебраїчними рівняннями 74000 за часовий горизонт 240s за 350s (минулий час). Я скоротив це до 170-х, використовуючи OpenMP для паралелізації. Тепер мені потрібно запустити кілька справ паралельно (підмітати для перевірки безпеки).
electrique

4
@BillBarth занадто скромний у продажі своїх навичок C ++, але він також занадто щедрий у своєму твердженні, що "повільність C ++ перепродана". У scicomp.stackexchange.com було багато тем C ++ проти Fortran, які обговорили саме це питання, і загальний висновок полягав у тому, що це просто неправда, ніж C ++ повільніше, ніж Fortran майже для всіх випадків. Я особисто думаю, що сьогодні це можна вважати міським міфом. Що це дуже вірно, що якщо взяти до уваги ремонтопридатності коду, то Fortran НЕ тариф дуже добре сьогодні.
Вольфганг Бангерт

2
@BillBarth та інші, якщо ви хочете продовжувати обговорювати загальні достоїнства Fortran, C ++ та інших мов, будь ласка, віднесіть його до кімнати чатів scicomp і будь-кого, кого ви хочете конкретно звернутись.
Арон Ахмадія

1
@AronAhmadia: ах, давай, мені так багато сказати Джеду ;-) (Jed: якийсь інший час. У нашому випадку немає STL для розріджених матриць, але багато в адаптивних мережевих структурах даних.)
Вольфганг Бангерт

Відповіді:


19

Дозвольте спробувати розбити ваші вимоги:

  • Технічне обслуговування
  • Читання / запис текстових даних
  • Міцні інтерфейси / можливості для LU-факторизації
  • Рідкі лінійні розв'язувачі
  • Продуктивність та масштабованість великих даних

З цього списку я розглядаю наступні мови:

C, C ++, Fortran, Python, MATLAB, Java

Юлія - ​​це багатообіцяюча нова мова, але спільнота все ще формується навколо неї, і вона не розгорнута в жодних основних нових кодах.

Читання / запис текстових даних

Це легко отримати правильно на будь-якій мові програмування. Переконайтеся, що ви належним чином буферизуєте та з’єднуєте доступ до вводу-виводу, і ви отримаєте хороші показники роботи з будь-якої з мов, які ви повинні врахувати. Уникайте об'єктів потоку в C ++, якщо ви не знаєте, як їх ефективно використовувати.

Міцні інтерфейси / можливості для LU-факторизації

Якщо ви виконуєте щільні фактори LU, вам потрібно використовувати паралельну функціональність LAPACK або ScaLAPACK / Elemental. LAPACK і ScaLAPACK написані у Fortran, Elemental написано на C ++. Усі три бібліотеки є працездатними та добре підтримуваними та задокументованими. Ви можете інтерфейсувати в них будь-яку з мов, які слід врахувати.

Рідкі лінійні розв'язувачі

Прем'єр вільно доступні рідкісні лінійні розв'язувачі майже всі доступні через PETSc , написаний на C, який добре задокументований та підтримується. Ви можете інтерфейсувати в PETSc з будь-якої з мов, які слід врахувати.

Продуктивність та масштабованість великих даних

Єдиними парадигмами паралельного програмування, які ви згадуєте, є спільна пам'ять, що означає, що ви не розглядаєте обчислювальний підхід на основі MPI (передачі повідомлень), розподіленої пам'яті. На мій досвід, набагато простіше написати код, який масштабує значно більше десятка ядер, використовуючи рішення з розподіленою пам'яттю. Майже всі університетські «кластери» є заснованими на MPI в наші дні, великі машини спільної пам’яті дорогі і відповідно рідкісні. Ви повинні врахувати MPI для свого підходу, але моя порада застосовуватиметься незалежно від обраної вами парадигми програмування.

Що стосується продуктивності на вузлі, якщо ви самі пишете числові процедури, найпростіше отримати хороші серійні показники у Fortran. Якщо у вас є трохи досвіду роботи з C, C ++ або Python, ви можете отримати дуже порівнянні показники роботи (C і C ++ мертві, навіть якщо Fortran, Python і MATLAB приходять приблизно за 25% накладні витрати без особливих зусиль). MATLAB робить це за допомогою компілятора JIT і дуже гарної експресивності лінійної алгебри. Ймовірно, вам потрібно буде використовувати Cython, numpy, numexpr або вбудувати числові ядра, щоб отримати заявлену продуктивність від Python. Я не можу коментувати продуктивність Java, тому що я не дуже добре знаю мову, але підозрюю, що це недалеко від Python, якщо її написав експерт.

Примітка про інтерфейси

Сподіваюся, я переконав вас, що ви зможете робити все, що завгодно, на будь-якій з мов програмування, які ви розглядаєте. Якщо ви використовуєте Java, інтерфейси C будуть трохи складними. Python має чудову підтримку інтерфейсів C та Fortran через ctypes, Cython та f2py. LAPACK вже обгорнутий і доступний через scipy. MATLAB має весь функціонал, який вам потрібен у своїх рідних бібліотеках, але його не можна легко масштабувати або особливо легко працювати на кластерах. Java може підтримувати інтерфейси C і Fortran з JNI , але зазвичай не зустрічається на кластерах і паралельному програмному забезпеченні для наукових обчислень.

Технічне обслуговування

Багато цього зводиться до особистого смаку, але загальний консенсус щодо ремонтопридатності полягає в тому, що ви хочете мінімізувати кількість рядків коду у вашому програмному забезпеченні, писати модульний код з чітко визначеними інтерфейсами та для обчислювального програмного забезпечення. тести, що підтверджують правильність та функціональність реалізації.

Рекомендація

Особисто мені пощастило з Python, і я рекомендую його для багатьох обчислювальних проектів. Думаю, ви повинні чітко врахувати це для свого проекту. Python та MATLAB, мабуть, найбільш виразні з мов, доступних для наукових обчислень. Ви можете легко інтерфейсувати Python з будь-якою іншою мовою програмування. Ви можете використовувати f2py, щоб обернути поточну реалізацію Fortran і переписати по частинах ті частини, які ви бажаєте в Python, перевіривши, що ви підтримуєте функціональність. У цей час я рекомендував би поєднувати офіційну реалізацію Python 2.7 з scipy . Ви можете дуже легко розпочати цей стек із вільно доступного дистрибутива Enthought Python .

Ви також можете зробити більшість цього в C, C ++ або Fortran. C і C ++ є дуже привабливими мовами для професійних розробників з великим досвідом роботи, але часто відвідують нових розробників і, мабуть, у цьому сенсі не є чудовою ідеєю для більш академічного коду. Fortran та MATLAB користуються популярністю в академічних обчисленнях, але слабкі в передових структурах даних та експресивності, які пропонує Python (подумайте, наприклад, про об'єкт диктанту Python).

Пов’язані запитання:


1
Дуже добре задокументована, всеосяжна відповідь. Під Fortran я використовую багато Lapack. Я погляну на python і спробую завернути свій код Fortran для початку і повільно повільно перейду до Python. Єдине, що мене лякає - це 25-відсотковий накладний час, який я міг би мати. Але якщо він виграє з більш виразним кодом і кращим паралельним керуванням обчисленнями, я піду для цього. Я згадував спільну пам'ять лише тому, що програмне забезпечення в даний час працює в інтерактивному режимі (внести зміни в дані і повторно) на 2,4,8,24,48-ядерних комп'ютерах спільної пам'яті дослідників Uni в Windows та Linux.
electrique

3
Я не знаю, як можна зробити претензію на 25% накладних витрат на числові ядра, написані на Python. Чисті ядра Python часто на 100 разів повільніше, ніж C. Numpy та numexpr можуть зробити гідну роботу з певними виразами, але це навряд чи записувати нові числові ядра в Python. Cython може зробити деякі речі швидкими, але зазвичай не в межах 25% від C. Python - це чудова мова, що "склеює", але я думаю, що Арон переробляє це як загальне рішення для завдань, що залежать від продуктивності.
Джед Браун

I / O є слабкою точкою Fortran, тому що Fortran вимагає багато структури в I / O. Мій досвід у спілкуванні з колегами з моєї лабораторії, які працюють із Cython, відповідає тому, що Джед каже про Cython; принаймні один з них пише вручну налаштований C, щоб замінити Cython для виконання завдань, що інтенсивно працюють, і тоді я вважаю, що ефективність Python, що викликає отриманий код C, ближче до претензії Арона. Крім того, якщо ви збираєтесь згадати PETSc та Python, ви можете також згадати petsc4py. Востаннє я бачив (це було кілька років тому), для Java не було хороших MPI-інтерфейсів. Це змінилося?
Джефф Оксберрі

@GeoffOxberry: Прив'язки Java MPI існують, але не оновлювалися майже десятиліття. Я вважаю їх статус сумнівним. У Fortran є безліч варіантів вводу / виводу, які можна зробити дуже швидкими. Я рекомендую вивчити паралельний HDF5 (і HDF5, як правило). Якщо введення-виведення дійсно домінуюче (більше 50% часу запуску), можуть бути серйозніші заходи, але в іншому випадку якість та портативність інтерфейсу, подібного до HDF, напевно, варто того.
Білл Барт

@BillBarth: мені доведеться це перевірити. Мій коментар щодо вводу / виводу Fortran походить з точки зору того, хто раз рекомендує мені написати аналізатор вхідних файлів у Fortran. Це можливо, застосувавши велику структуру, але я просто не бачив легко та широко використовуваних регекс-аналізаторів чи бібліотек парсерів XML у Fortran (щоб навести кілька прикладів). Для цього є вагомі причини: ми єдині люди, які вже використовують Fortran. Можливо, ми думаємо про різні випадки використання.
Джефф Оксберрі

2

Окрім дуже вичерпної відповіді Арона, я погляну на різні теми на 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) . Ми використовуємо його в deal.II вже кілька років з хорошими результатами. Про це також є дуже хороша книга.

(iv) Я маю власну думку щодо OpenMP, а саме, що це рішення в пошуках проблеми. Він добре працює для паралелізації внутрішніх циклів, що може зацікавити, якщо у вас є дуже регулярні структури даних. Але це рідко, що ви хочете зробити, якщо вам потрібно щось паралелізувати - адже те, що ви насправді хочете зробити, це паралелізувати зовнішні петлі. І для цього такі рішення, як TBB, є набагато кращими рішеннями, оскільки вони використовують механізми мови програмування, а не намагаються описати те, що відбувається поза мовою (через #pragmas) і таким чином, що у вас немає доступу до ручок потоку. , показники стану результатів тощо тощо з вашої програми.

(v) Якщо ви експериментуєте, ви також можете ознайомитись з новими мовами програмування, призначеними для паралельного програмування, і, зокрема, для таких завдань, як описані вами. По суті, я би поглянув на два: X10 та Chapel . Я бачив гарні підручники на Каплиці, і це здається добре розробленим, хоча обидва, звичайно, сьогодні також є острівними рішеннями.


Для запису Intel стверджує, що в їх поточні компілятори вбудований паралельний (розподілену пам'ять) масив Fortran. Ми розглядаємо це в TACC, але я ще нічого не можу повідомити. Cray також має реалізацію у своєму компіляторі, але це доступно лише на невеликій цілій кількості машин у всьому світі. Я не думаю, що ніхто не впроваджує повний стандарт Fortran 2008 щодо ко-масивів, але в декількох компіляторах є підтримка, яка нараховується. Cilk +, звичайно, також доступний у компіляторах Intel, але бути надійним, мабуть, ще не розумно.
Білл Барт

Стандарт Fortran 2008 не був затверджений до кінця 2010 року, тому минуло кілька років, поки CAF стане широко доступним. G95 насправді мав (невільну) реалізацію, але більше не розробляється (розробник приєднався до PathScale).
stali

Більшість g95 врешті-решт опинилися в gfortran, але, можливо, CAF не є частиною цього.
Вольфганг Бангерт

Я вважаю, що компілятор Intel забезпечує хорошу підтримку спільного масиву. Вони створили його за допомогою mpiexec. Це не буде моїм першим вибором. Приємно те, що та сама реалізація може працювати на спільній та розподіленій пам’яті (я провів кілька тестів). Коли процесори спільної пам’яті opteron досягають 60-ядер за дійсно розумними цінами, я спершу хочу побачити свої параметри спільної пам’яті.
electrique

2

Як правило, якщо ви дійсно серйозно ставитесь до цього програмного проекту, я б запропонував повністю переписати будь-якою мовою, з якою ви відчуваєте себе найбільш комфортно. Це здається, що ви будете виконувати роботу поодинці, і тому ви отримаєте найкращі результати на тій мові, якою ви відчуваєте себе вдома.

Більш конкретно, проте, щодо паралелізму, я б закликав вас спробувати трохи подумати поза рамкою. OpenMP має свої сильні сторони, але він застряг у думці взяти послідовний код і прищеплювати паралелізм тут і там. Те саме стосується Intel TBB.

Cilk , безумовно, є кроком у правильному напрямку, тобто змушує вас переосмислити свою проблему / рішення в паралельній установці. Що мені в цьому не подобається, це те, що це ще одна мова . Крім того, оскільки він може лише грунтуватися на зв'язках між паралельними завданнями, планувальник може бути досить консервативним і не може бути масштабним для певних проблем.

Хороша новина полягає в тому, що, знову ж таки, якщо ви серйозно ставитеся до своєї реалізації, ви можете робити те, що робить Cilk, наприклад, переписати свою проблему як набір взаємозалежних завдань і розподілити їх по ряду процесорів / ядра, все самостійно, використовуючи pthreads або неправильно використовуючи OpenMP для нерестуючих процесів. Гарний приклад того, як це можна зробити, - це планувальник QUARK, який використовується в бібліотеці PLASMA . Приємне порівняння його продуктивності проти Cilk наведено тут .


Я перегляну запропоновані посилання. Папір для порівняння дуже приємний! Спасибі! Я думав про pthreads, але хочу, щоб програма була кросплатформою. Як я знаю, у pthreads виникають проблеми під Windows (неправильно?).
electrique

@ p3tris: "p" у pthreads призначений для POSIX, тому він є настільки ж портативним, як це може бути. Існує кілька сумісних реалізацій Windows, таких як проект pthreads-win32або в межах нього cygwin.
Педро

На основі stackoverflow.com/q/2797690/801468 я бачу, що для впорядкування потрібно багато матеріалів. Зважаючи на те, що я не програміст, я вважаю за краще дотримуватися чогось більш перевіреного.
electrique

2

У вищезазначених коментарях мало обговорювати питання про coarray fortran. У цей час, і наскільки мені відомо, підтримка coarray у компіляторах приблизно така:

  • У Cray є компілятор, який підтримує принаймні основні функції coarray. Я використовував його для написання коду, який мав бути "навчальним", але я б сказав, що ви можете написати реальний код у coarray fortran. Синтаксис та поняття здебільшого набагато простіші, ніж MPI, але, як завжди, є лотоси лоти, а пастки відрізняються від MPI.
  • Intel fortran має підтримку coarray, побудовану на базі бібліотеки MPI. Нібито це обмежує їх теоретичну пікову ефективність, але я не бачив жодної метрики.
  • Gfortran підтримує coarrays, але лише для одного зображення (або одиночного рангу, в MPI говорять). Отже, реальна паралелізація не доступна, поки не вийде gfortran 4.8 або 4.9.

Як правило, я буду обережним, якщо запустити код на основі coarray. Синтаксис простий і набагато зручніший, ніж Fortran / C / C ++ з MPI, але тоді він просто не такий повнофункціональний. Наприклад, MPI підтримує безліч операцій скорочення тощо, що може бути дуже зручно для вас. Це дійсно залежало б від вашої потреби у великій кількості спілкування. Якщо ви хочете прикладу, дайте мені знати, і я можу надати вам декілька, якщо зможу викопати файли.


Так, більше інформації про готовність coarray Fortran до подібних проблем, безумовно, буде корисною. Ласкаво просимо до scicomp!
Арон Ахмадія

1

Погляньте на Spark - це розподілений фреймворк для обчислень в пам'яті, який використовує переваги функціонального програмування. Структура програми в Spark сильно відрізняється порівняно з MPI, в основному ви пишете код, як для одного комп'ютера, який автоматично розподіляється як функції на дані, що знаходяться в пам'яті. Він підтримує Scala, Java та Python.

Логістична регресія (масштаб):

//load data to distributed memory
val points = spark.textFile(...).map(parsePoint).cache()
var w = Vector.random(D) // current separating plane
for (i <- 1 to ITERATIONS) {
  val gradient = points.map(p =>
    (1 / (1 + exp(-p.y*(w dot p.x))) - 1) * p.y * p.x
  ).reduce(_ + _)
  w -= gradient
}
println("Final separating plane: " + w)

Існує розширення, яке називається MLib (Бібліотека машинного навчання), яке використовує бібліотеку Fortran для деяких обчислень низького рівня (для Python, я думаю, використовується numpy). Отже, ідея проста, сконцентруйтеся на своєму алгоритмі та залиште оптимізацію на нижчих рівнях (порядок обробки, розподіл даних тощо).

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.