Чи легше оптимізувати Fortran, ніж C для важких розрахунків?


410

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

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


53
Нетипові суб’єктивні з наведених нижче відповідей. Правильна назва: "Чи є фундаментальні архітектурні причини, через які компілятор Fortran MIGHT виробляє краще оптимізований код, ніж компілятор C", але це лише вибирання ниток.
Мартін Бекетт

3
Заголовок питання не настільки суб'єктивний, як це непорозуміння, я думаю. Більш детальне питання не є суб'єктивним.
jfm3

1
Я не думаю, що хтось багато чого з цього не навчиться, окрім того, що відповіді є "Так" і "Ні" одночасно, і змінюється залежно від компілятора, джерела, процесора, компонування пам'яті і т. Д. І т.д. тощо.
user7116

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

2
@sixlettervariables, хоча ви і я вже знаємо відповідь, це питання, яке виникає у більшості людей на початку їхньої кар’єри і важливо зрозуміти відповідь. Замість того, щоб оприлюднити коментар, чому б не знайти відповідь, з якою ви погоджуєтесь, і дати +1
MarkJ

Відповіді:


447

Мови мають подібні набори функцій. Різниця в продуктивності пов'язана з тим, що Fortran каже, що дозвол не дозволений, якщо не буде використано оператор EQUIVALENCE. Будь-який код, який має псевдонім, не є дійсним Fortran, але це визначає помилки, а не програміст, а не компілятор. Таким чином, компілятори Fortran ігнорують можливе псевдонім покажчиків пам'яті і дозволяють їм генерувати більш ефективний код. Погляньте на цей невеликий приклад на С:

void transform (float *output, float const * input, float const * matrix, int *n)
{
    int i;
    for (i=0; i<*n; i++)
    {
        float x = input[i*2+0];
        float y = input[i*2+1];
        output[i*2+0] = matrix[0] * x + matrix[1] * y;
        output[i*2+1] = matrix[2] * x + matrix[3] * y;
    }
}

Ця функція працюватиме повільніше, ніж аналог Fortran після оптимізації. Чому так? Якщо ви записуєте значення у вихідний масив, ви можете змінити значення матриці. Зрештою, вказівники можуть перекриватися і вказувати на той самий шматок пам'яті (включаючи intвказівник!). Компілятор C змушений перезавантажити чотири значення матриці з пам'яті для всіх обчислень.

У Fortran компілятор може один раз завантажити матричні значення і зберегти їх у регістри. Це може зробити так, оскільки компілятор Fortran передбачає, що вказівники / масиви не перетинаються в пам'яті.

На щастя, restrictключове слово та суворе псевдонім було введено до стандарту C99 для вирішення цієї проблеми. Він добре підтримується в більшості компіляторів C ++ і в наші дні. Ключове слово дозволяє дати компілятору підказку, що програміст обіцяє, що покажчик не має псевдоніму з будь-яким іншим вказівником. Строгий-альясінг означає , що програміст обіцяє , що покажчики різного типу ніколи не перекривається, наприклад, double*НЕ буде перекриватися з int*(з конкретного винятку того, що char*і void*може перекриватися з чим - або).

Якщо ви їх використовуєте, ви отримаєте однакову швидкість від C і Fortran. Однак можливість використання restrictключового слова лише з критичними функціональними функціями означає, що програми C (і C ++) набагато безпечніше і простіше писати. Наприклад, розглянемо недійсний код Fortran:, CALL TRANSFORM(A(1, 30), A(2, 31), A(3, 32), 30)який більшість компіляторів Fortran з радістю буде компілювати без будь-якого попередження, але вводить помилку, яка відображається лише на деяких компіляторах, на деяких апаратних засобах та з деякими параметрами оптимізації.


26
Все вірно і дійсно, Джефф. Однак, я не вважаю перемикач "припускати не згладжування" безпечним. Він може порушити код, успадкований від інших проектів настільки витончені способи, що я краще не використовую його. З цієї причини я став нацистським обмежувачем :-)
Нілс Піпенбрінк

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

33
Хороший приклад - просте існування memcpy () vs. memmove (). На відміну від memcpy (), memmove () справляється із ділянками, що перекриваються, тому memcpy () може бути швидшим, ніж memmove (). Ця проблема була достатнім приводом для того, щоб хтось включив дві функції замість однієї у стандартну бібліотеку.
jfs

12
Я думаю, що це було сенсом Себастьяна - через складність / гнучкість управління пам'яттю С, навіть щось таке просте, як переміщення пам'яті, є хитромудрим.
Мартін Бекетт

3
Ваш call transformприклад не має великого сенсу.
Володимир Ф

163

Так, у 1980 році; у 2008 році? залежить

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

Тож у мене є два погляди на це, теоретичні та практичні. Теоретично, Fortran сьогодні не має внутрішньої переваги перед C / C ++ або навіть будь-якою мовою, яка дозволяє збірний код. На практиці Fortran сьогодні все ще користується перевагами спадщини історії та культури, побудованої на основі оптимізації числового коду.

До і не включаючи Fortran 77, питання дизайну мови були оптимізацією як основний акцент. Через стан теорії та технології компілятора це часто означало обмеження функцій та можливостей, щоб дати компілятору найкращий результат для оптимізації коду. Хороша аналогія - думати про Fortran 77 як професійний гоночний автомобіль, який жертвує функціями для швидкості. У наші дні компілятори стали кращими на всіх мовах, а продуктивність програміста більше цінується. Однак все ще є місця, де людей в основному хвилює швидкість наукових обчислень; ці люди, швидше за все, успадкували код, навчання та культуру від людей, які самі були програмістами Fortran.

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

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

(Скорочена версія цієї відповіді була б коментарем у чудовій темі, яку розпочав Нілс, але я не маю карми, щоб це зробити. Насправді я, мабуть, взагалі нічого б не написав, але для того, щоб ця тема була фактичною інформаційний зміст та обмін на відміну від полум’яних воєн та мовної фанатики, що є моїм головним досвідом роботи з цією темою. Я був переповнений і повинен був поділитися любов'ю.)


1
посилання: web.archive.org/web/20090401205830/http://ubiety.uwaterloo.ca/… більше не працює. Чи існує альтернативна посилання?
nathanielng

64

В якійсь мірі Fortran був розроблений, враховуючи оптимізацію компілятора. Мова підтримує операції з цілим масивом, де компілятори можуть використовувати паралелізм (особливо на багатоядерних процесорах). Наприклад,

Множення щільної матриці просто:

matmul(a,b)

Норма L2 вектора x дорівнює:

sqrt(sum(x**2))

Більше того, такі оператори, як FORALL, PURE& ELEMENTALпроцедури тощо надалі допомагають оптимізувати код. Навіть вказівники у Фортран не такі гнучкі, як C через цю просту причину.

Майбутній стандарт Fortran (2008) має спільні масиви, що дозволяє легко писати паралельний код. G95 (відкритий код) та компілятори від CRAY вже підтримують його.

Так, так, Fortran може бути швидким просто тому, що компілятори можуть оптимізувати / паралелізувати його краще, ніж C / C ++. Але знову ж таки, як і все в житті, є хороші компілятори і погані компілятори.



1
forallКонструкція застаріла , тому що укладачі не змогли оптимізувати код добре. Заміна є do concurrent. Також код sqrt(sum(x**2))виглядає неефективним, оскільки компілятор, ймовірно, конструює весь вектор x**2. Я б здогадався, що цикл кращий, але, безперечно, найкраще викликати внутрішню norm2функцію.
A. Hennink

39

Смішно, що тут багато відповідей з невідомості мов. Особливо це стосується програмістів на C / C ++, які відкрили і старий код FORTRAN 77 і обговорюють слабкі сторони.

Я гадаю, що проблема швидкості - це здебільшого питання між C / C ++ та Fortran. У величезному коді це завжди залежить від програміста. Є деякі особливості мови, які Фортран перевершує, і деякі особливості, якими володіє С. Так, у 2011 році ніхто реально не може сказати, хто з них швидший.

Що стосується самої мови, Fortran в даний час підтримує функції Full OOP, і вона повністю сумісна з зворотною стороною. Я ретельно використовував Fortran 2003, і ​​я б сказав, що це було просто приємно використовувати його. У деяких аспектах Fortran 2003 все ще відстає від C ++, але давайте розглянемо використання. Fortran в основному використовується для чисельних обчислень, і ніхто не використовує привабливі функції C ++ OOP через причини швидкості. У високопродуктивних обчисленнях C ++ майже нікуди йти (подивіться на стандарт MPI, і ви побачите, що C ++ застаріло!).

Сьогодні ви можете просто робити змішане мовне програмування за допомогою Fortran та C / C ++. У Fortran є навіть інтерфейси для GTK +. Є безкоштовні компілятори (gfortran, g95) та багато відмінних комерційних.


8
Не могли б ви додати джерело, специфічний досвід чи науковий інститут / високоефективне обчислювальне агентство, яке або відходить від C ++ для майбутніх проектів, або переписує проекти c ++ на іншу мову. Я прошу лише тому, що знаю щонайменше дві наукові установи, Сандію та ЦЕРН, які активно використовують c ++ для моделювання високої продуктивності. Крім того, Sandia перетворила одне із своїх програм для моделювання (LAMMPS) з fortran на c ++, додавши ряд дивовижних удосконалень.
Захарій Краус

7
LAMMPS написаний на надзвичайно простому C ++, що не використовує переваги більшості сучасних особливостей мови. Він являє собою C ++, який пишуть програмісти Fortran, які знають C, вивчаючи C ++ 98. Це не означає, що LAMMPS написано погано, лише те, що це не той приклад, який ви хочете навести, відстоюючи C ++ у HPC.
Джефф

30

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

  • ЧИСТО та ЕЛЕМЕНТАРНІ ключові слова щодо функцій Це функції, які не мають побічних ефектів. Це дозволяє оптимізувати в певних випадках, коли компілятор знає, що однакова функція буде викликана з однаковими значеннями. Примітка: GCC реалізує "pure" як розширення до мови. Інші компілятори також можуть. Міжмодульний аналіз також може виконати цю оптимізацію, але це важко.

  • стандартний набір функцій, які мають справу з масивами, а не окремими елементами. Такі речі, як sin (), log (), sqrt (), беруть масиви замість скалярів. Це полегшує оптимізацію розпорядку. Автовекторизація дає однакові переваги в більшості випадків, якщо ці функції є вбудованими або вбудованими

  • Вбудований комплексний тип. Теоретично це могло б дозволити компілятору змінити порядок або усунути певні інструкції в певних випадках, але, ймовірно, ви побачите ту саму вигоду із структурою {double re, im; }; ідіома, що використовується в C. Це сприяє більш швидкому розвитку, хоча оператори працюють над складними типами у фортран.


1
"але, ймовірно, ви побачите ту саму вигоду з { double re, im; };ідіомою структури, що використовується в C". Компілятори C, швидше за все, повернуть цю структуру в щасливій формі, коли стек виклику виділяє простір, передаючи вказівник на заклик, який заповнює його. Це в кілька разів повільніше, ніж повернення кількох значень у регістри, як би компілятор Fortran. Зауважте, що C99 виправив це у спеціальному випадку складного.
Джон Харроп

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

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

28

Я думаю, що ключовим моментом на користь Фортран є те, що це мова трохи більше підходить для вираження математики на основі вектора та масиву. Вищезазначена проблема аналізу вказівників на практиці реальна, оскільки портативний код насправді не може припустити, що ви можете сказати компілятору щось. ЗАВЖДИ є перевага для вираження обчислювачів таким чином, що ближче до того, як виглядає домен. C насправді взагалі не має масивів, якщо придивитись уважно, просто щось подібне поводиться. Фортран має справжні масиви. Що полегшує компіляцію для певних типів алгоритмів, особливо для паралельних машин.

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


25

Немає того, щоб одна мова була швидшою за іншу, тому правильна відповідь - ні .

Те, що ви насправді повинні запитати, це "чи компілюється код за допомогою компілятора Fortran X швидше, ніж еквівалентний код, зібраний з компілятором C Y?" Відповідь на це питання звичайно залежить від того, які два компілятори ви виберете.

Ще одне питання, яке можна задати, було б таким чином: "Враховуючи стільки ж зусиль, які вкладаються в оптимізацію в їх компіляторах, який компілятор створить швидший код?" Відповідь на це насправді буде Фортран . Компілятори Fortran мають сертифікатні переваги:

  • Ще в той день, коли деякі обіцяли ніколи не використовувати компілятори, Fortran довелося конкурувати з асамблеєю, тому це було розроблено для швидкості. C був розроблений так, щоб бути гнучким.
  • У ніші Фортрана було чисельність. У цьому доменному коді ніколи не буває досить швидко. Тому завжди було чимало тиску, щоб зберегти мову ефективно.
  • Більшість досліджень оптимізації компілятора проводиться людьми, зацікавленими в прискоренні коду скорочення числа Fortran, тому оптимізація коду Fortran є набагато відомішою проблемою, ніж оптимізація будь-якої іншої мови, що склалася, і нові інновації з’являються вперше в компіляторах Fortran.
  • Biggie : C заохочує набагато більше використання покажчика, ніж Fortran. Це різко збільшує потенційний обсяг будь-якого елемента даних у програмі C, що ускладнює їх оптимізацію. Зауважте, що Ада також значно краща за С у цій царині, і є набагато сучаснішою мовою ОО, ніж зазвичай зустрічається Fortran77. Якщо ви хочете OO-ланцюг, який може генерувати швидший код, ніж C, це варіант для вас.
  • Завдяки своїй чисельній ніші, клієнти компіляторів Fortran прагнуть більше дбати про оптимізацію, ніж клієнти компіляторів C.

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


4
Я згоден. І чи можу я додати, що коли введено Фортран (це була перша мова на високому рівні) наприкінці 50-х на початку 60-х, багато хто скептично ставився до того, наскільки це може бути ефективно. Тому його розробникам довелося довести, що Fortran може бути ефективним і корисним, і готові «оптимізувати його до смерті» лише для того, щоб довести свою думку. C прийшов набагато пізніше (на початку середини 70-х) і не мав нічого доводити, так би мовити. Але до цього часу було написано дуже багато коду Фортран, щоб наукове співтовариство дотримувалося цього і досі. Я не програмую Fortran, але я навчився зв'язуватися, щоб викликати підпрограми Fortran із C ++.
Олумід

3
Дослідження оптимізації компілятора були різноманітнішими, ніж вам здається. Наприклад, історія впровадження LISP наповнена успіхами в тому, щоб численні показники скорочувалися швидше, ніж Fortran (який залишається претендентом за замовчуванням). Крім того, величезна частина оптимізації компілятора має націлені проміжні уявлення про компілятор, а це означає, що відмінності в семантиці вбік (на зразок псевдоніму) вони стосуються будь-якої мови програмування даного класу.
Ніде людина

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

@Praxeolitic - Це цілком правильно (саме тому мені приємно, що я нічого такого не сказав).
ТЕД

@TED ​​Чесно кажучи, повертаючись сюди через кілька місяців, я не маю поняття, чому я залишив цей коментар до вашої відповіді. Може, я мав намір залишити його десь ще? XP
Praxeolitic

22

Є ще один предмет, де Fortran відрізняється від C - і потенційно швидший. Фортран має кращі правила оптимізації, ніж C. У Fortran порядок оцінювання виразів не визначений, що дозволяє компілятору оптимізувати його - якщо хочеться примусити певний порядок, треба використовувати дужки. У C порядок набагато суворіший, але з опціями "-fast" вони більш спокійні, і "(...)" також ігноруються. Я думаю, що у Фортрана є шлях, який гарно лежить посередині. (Ну, IEEE робить складнішим життя, оскільки деякі зміни порядку замовлення вимагають, щоб не виникало переповнення, яке або має бути ігноровано, або перешкоджає оцінці).

Ще одна область розумніших правил - складні числа. Мало того, що до C 99 минуло, що C мав їх, а правила у них краще у Фортран; Оскільки бібліотека Fortran gfortran частково написана на C, але реалізує семантику Fortran, GCC отримав варіант (який також можна використовувати з "звичайними" програмами C):

-fcx-fortran-правила Складне множення та ділення слідують правилам Фортран. Скорочення діапазону проводиться як частина складного поділу, але не перевіряється, чи є результатом складного множення чи ділення "NaN + I * NaN", намагаючись врятувати ситуацію в цьому випадку.

Згадані вище правила псевдоніму - це ще один бонус, а також - принаймні в принципі - операції з цілим масивом, які при правильному врахуванні оптимізатором компілятора можуть призвести до швидшого кодування. З іншого боку, певна операція займає більше часу, наприклад, якщо присвоєння виділеному масиву потрібно багато перевірок (перерозподілити? [Функція Fortran 2003], чи мають кроки масиву тощо), які роблять проста операція є більш складною за кадром - і тим самим повільніше, але робить мову більш потужною. З іншого боку, операції з масивом з гнучкими межами та кроками полегшують запис коду - і компілятор, як правило, краще оптимізує код, ніж користувач.

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


Що є значущим "порятунком" у випадку Nan + INan? Що нескінченності відрізняється від NaN, це те, що нескінченності підписані. Операції, пов’язані з нескладними нескінченностями, які давали б заплутаний знак, дають NaN, і я не бачу причини, що складні числа не повинні робити інакше. Якщо один кратний (DBL_MAX, DBL_MAX) на (2,2), квадрат квадратів результату, а потім квадрати, які отримали результат, що має бути ознакою результату за відсутності переповнення? Що таке замість цього множиться на (1.001, DBL_MAX)? Я вважаю (NaN, NaN) правильною відповіддю, а будь-яке поєднання нескінченності та NaN як безглузде.
supercat

14

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

Протягом багатьох років існували компілятори Fortran, які могли зробити чорну магію для ваших числових процедур, зробивши багато важливих обчислень шалено швидко. Сучасні компілятори C також не могли це зробити. Внаслідок цього у Фортран зросла низка чудових бібліотек коду. Якщо ви хочете використовувати ці добре перевірені, зрілі, чудові бібліотеки, ви вириваєте компілятор Fortran.

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


11
Майже оновив це. Проблема полягає в тому, що Fortran дійсно мають деякі переваги , властиві. Однак ви досить привітні, що важливо звернути увагу на компілятор, а не на мову.
ТЕД

14

Я порівнюю швидкість Фортран, С і С ++ з класичним показником Левіна-Каллахан-Донгарра від netlib. Версія з декількома мовами, з OpenMP, http://sites.google.com/site/tprincesite/levine-callahan-dongarra-vectors C є більш кричущою, як це почалося з автоматичного перекладу, плюс додавання обмежень та прагм для певних компілятори. C ++ - це лише C із шаблонами STL, де це можливо. На мій погляд, STL - це змішаний мішок щодо того, чи покращує він ремонтопридатність.

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

У компілятора C / C ++, який на сьогодні має найпоширеніше використання, не вистачає автоматичної векторизації, на яку ці орієнтири сильно покладаються.

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


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

12

Я програвач-хобіст, і я "середній" на обох мовах. Мені легше писати швидкий код Fortran, ніж C (або C ++). І Fortran, і C - це "історичні" мови (на сьогоднішній день стандартні), які широко використовуються та добре підтримують безкоштовний та комерційний компілятор.

Я не знаю, чи це історичний факт, але Фортран відчуває, що він побудований для паралельної / розподіленої / векторизованої / будь-якої-багатьох ядер. І сьогодні це майже "стандартна метрика", коли ми говоримо про швидкість: "чи масштабується вона?"

Для чистого хрускоту процесора я люблю Fortran. Для будь-якого, що стосується IO, мені легше працювати з C. (в обох випадках це важко в будь-якому випадку).

Звичайно, для паралельного математичного інтенсивного коду ви, мабуть, хочете використовувати свій графічний процес. І C, і Fortran мають багато більш-менш добре інтегрованого інтерфейсу CUDA / OpenCL (і зараз OpenACC).

Моя помірно об'єктивна відповідь: Якщо ви знаєте обидві мови однаково добре / погано, то я думаю, що Фортран швидше, тому що мені легше писати паралельний / розподілений код у Фортран, ніж C. (як тільки ви зрозуміли, що можете написати "freeform" fortran і не просто суворий код F77)

Ось 2-а відповідь для тих, хто бажає звернути увагу на мене, оскільки їм не подобається перша відповідь: Обидві мови мають функції, необхідні для написання високопродуктивного коду. Отже, це залежить від алгоритму, який ви впроваджуєте (процесорний інтенсивний? Інтенсивний? Інтенсивний об'єм пам'яті?), Апаратного забезпечення (одиночний процесор? Багатоядерний? Розповсюджують суперкомп'ютер? GPGPU? FPGA?), Вашої майстерності та в кінцевому рахунку самого компілятора. І C, і Fortran мають дивовижний компілятор. (Я серйозно вражений тим, наскільки просунуті компілятори Fortran є, але так само є і компілятори C).

PS: Я радий, що ви спеціально виключили лайб, тому що у мене є багато поганого, що можна сказати про губи FortI GUI. :)


11

Я займався декількома обширними математиками з FORTRAN і C протягом двох років. З власного досвіду можу сказати, що FORTRAN іноді дійсно кращий за C, але не за його швидкістю (можна змусити C виконувати так само швидко, як FORTRAN, використовуючи відповідний стиль кодування), а швидше через дуже добре оптимізовані бібліотеки, як LAPACK, і через велика паралелізація. На мою думку, FORTRAN справді незручно працювати, і його переваги недостатньо гарні, щоб скасувати цей недолік, тому зараз я використовую C + GSL для розрахунків.


10

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

У будь-якому випадку, хороший програміст може написати Fortran будь-якою мовою.


@Scott Clawson: у тебе -1'd, і я не знаю чому. Поставив +1, щоб виправити це. Однак щось враховувати, це те, що Фортран існував довше, ніж багато наших батьків. Багато часу, витраченого на оптимізацію виводу компілятора: D
user7116,

Я згоден. Я щойно паралельно розмістив дуже подібну відповідь.
Високий Джефф

Питання псевдоніму вказівника на C було порушено іншими, але є кілька методів, які програміст може використовувати на сучасних компіляторах для вирішення цього питання, тому я все одно згоден.
Високий Джефф

1
@Kluge: "Немає нічого важливого для Fortran, який би зробив це швидше, ніж C". Зменшення вказівника, повернення значень складових у регістри, вбудовані числові конструкції вищого рівня ...
Джон Харроп,

9

Я не чув, що Фортан значно швидший за С, але це може бути зрозуміло, що в деяких випадках це буде швидше. І ключ не в мовних особливостях, які є, а в тих, які (як правило) відсутні.

Прикладом є покажчики С. C покажчики використовуються досить скрізь, але проблема з вказівниками полягає в тому, що компілятор зазвичай не може визначити, чи вказують вони на різні частини одного масиву.

Наприклад, якщо ви написали процедуру strcpy, яка виглядала так:

strcpy(char *d, const char* s)
{
  while(*d++ = *s++);
}

Компілятор повинен працювати за припущенням, що d і s можуть перекривати масиви. Таким чином, він не може здійснити оптимізацію, яка б дала різні результати при перекритті масивів. Як і слід було очікувати, це значно обмежує вид оптимізації, який можна виконати.

[Я мушу зазначити, що C99 має ключове слово "обмежувати", яке чітко повідомляє компілятори, що покажчики не перетинаються. Також зауважте, що у Fortran теж є вказівники, семантика яких відрізняється від значень C, але покажчики не є всюдисущими, як у C.]

Але повертаючись до випуску C проти Fortran, можливо, компілятор Fortran здатний виконати деякі оптимізації, які можуть бути неможливі для (прямо написаної) програми C. Тож я не був би дуже здивований претензією. Однак я сподіваюся, що різниця у виконанні не буде такою великою. [~ 5-10%]


9

Швидке та просте: Обидва однаково швидкі, але Фортран простіший. Що дійсно швидше, врешті-решт, залежить від алгоритму, але різниця у швидкості все одно є значною. Про це я дізнався в майстерні Фортран в обчислювальному центрі міста Штутгард, Німеччина у 2015 році. Я працюю як з Fortran, так і з C і поділяю цю думку.

Пояснення:

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

Фортран був розроблений для наукового програмування. З цієї причини він підтримує запис швидкого синтаксису коду, оскільки це головна мета Fortran. На відміну від громадської думки, Fortran не є застарілою мовою програмування. Останній його стандарт - 2010 рік, і нові компілятори публікуються регулярно, оскільки більшість високоефективних кодів написані у Fortran. Крім того, Fortran підтримує сучасні функції як директиви компілятора (у C-прагмах).

Приклад: Ми хочемо дати велику структуру як вхідний аргумент функції (fortran: підпрограма). У межах функції аргумент не змінюється.

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

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


Чи можете ви написати нативну паралельну програму на C (тобто без виклику бібліотек?). Ні. Чи можете ви написати рідну паралельну програму у Fortran? Так, кількома різними способами. Ерго, Фортран "швидший". Хоча, якщо бути справедливим, у 2010 році, коли ви писали свій коментар, підтримка паралельних функцій Fort і Cora-масиву Fortran, ймовірно, не була настільки поширеною, як зараз.
Малі Реморкер

@MaliRemorker Він написав це у 2016 році, а не у 2010 році.
Ковальський

На мою думку, витрати на створення паралельних процесів не є найважливішим фактором для мови програмування, яка називається "швидкою". Більш актуальними є практичні міркування, як, наприклад, невиконання коду. Тож нічого не допоможе, якщо ви заощадите час один раз (при створенні паралельного процесу) і витратите його на кілька ядер пізніше. Термін "швидкий" також повинен враховувати непаралельні коди. З цієї причини я не бачу аргументу проти моєї точки зору. Можливо, ваш коментар був менталом як незалежна відповідь?
Маркус Дуцке

8

Зазвичай FORTRAN повільніше, ніж C. C може використовувати апаратні покажчики рівня, що дозволяють програмісту вручну оптимізувати. FORTRAN (у більшості випадків) не має доступу до апаратної пам'яті для адреси хаків. (VAX FORTRAN - інша історія.) Я використовував FORTRAN і вимикався з 70-х. (Дійсно.)

Однак, починаючи з 90-х років, FORTRAN перетворився на включення конкретних мовних конструкцій, які можна оптимізувати за властивими їм паралельними алгоритмами, які дійсно можуть кричати на багатоядерному процесорі. Наприклад, автоматична векторизація дозволяє безліч процесорів одночасно обробляти кожен елемент у векторі даних. 16 процесорів - 16 елементів елементів - обробка займає 1/16 часу.

У C ви повинні керувати власними потоками та ретельно розробити алгоритм для багатообробної обробки, а потім використовувати купу викликів API, щоб переконатися, що паралелізм відбувається належним чином.

У FORTRAN вам потрібно лише ретельно розробити алгоритм для багатообробної обробки. Компілятор і час виконання може обробити решту за вас.

Ви можете трохи прочитати про високоефективний Fortran , але ви знайдете багато мертвих посилань. Вам краще прочитати про паралельне програмування (як OpenMP.org ) і про те, як FORTRAN це підтримує.


6
@ S.Lott: Я не міг уявити, як жахливий код C повинен виглядати, щоб зробити так само добре, як просто написаний Fortran для більшості кодів, які ми маємо тут ..., і я програміст на C. Ви отримаєте кращу ефективність завдяки більш простому коду у Fortran. Не те, щоб ви чи я не змогли знайти контрприклад. : D
user7116

2
@Greg Rogers: Вам доведеться вирішити свою проблему з людьми Fortran Vectorization, а не я. Я просто доповідаю про прочитане. polyhedron.com/absoftlinux
S.Lott

2
-1 // "Взагалі FORTRAN повільніше, ніж C. Це справедливо майже для всього." чому? // Аргумент, заснований на простоті використання багатопотокової передачі у Fortran vs C, не говорить про продуктивність.
Steabert

4
@ S.Lott: "багатопотокова передача існує лише для продуктивності". Помилка, ні.
Джон Харроп

4
@ S.Lott: "Використання C покажчиків майже на апаратному рівні дозволяє C бути швидшим, ніж Fortran". Помилка, ні
Джон Харроп

5

Більш швидкий код насправді не залежить від мови, це компілятор, тому ви можете побачити ms-vb "компілятор", який генерує роздутий, повільніший і надлишковий об'єктний код, який пов'язаний між собою ".exe", але powerBasic генерує занадто спосіб кращий код. Код об'єкта, зроблений компіляторами C і C ++, генерується в деяких фазах (щонайменше 2), але за задумом більшість компіляторів Fortran мають щонайменше 5 фаз, включаючи оптимізацію високого рівня, тому проектний Fortran завжди матиме можливість генерувати високооптимізований код. Отже, наприкінці компілятор - це не мова, яку ви повинні просити, найкращий компілятор, який я знаю, - це компілятор Intel Fortran, тому що ви можете отримати його на LINUX та Windows, і ви можете використовувати VS як IDE, якщо ви шукаєте дешевий жорсткий компілятор, який ви завжди можете передати на OpenWatcom.

Більше інформації про це: http://ed-thelen.org/1401Project/1401-IBM-Systems-Journal-FORTRAN.html


3

Фортран має кращі підпрограми вводу / виводу, наприклад, мається на увазі, що програма робить гнучкість, що стандартна бібліотека C не може відповідати.

Компілятор Fortran безпосередньо обробляє більш складний синтаксис, що стосується, і оскільки такий синтаксис не може бути легко зведений до форми передачі аргументів, C не може ефективно його реалізувати.


1
У вас є орієнтири, які показують, що Fortran бив C для вводу / виводу?
Джефф

3

Використовуючи сучасні стандарти та компілятор, ні!

Деякі з людей припускають, що FORTRAN швидше, тому що компілятору не потрібно турбуватися про згладжування (і, отже, можна зробити більше припущень під час оптимізації). Однак це було розроблено в C з моменту стандарту C99 (я думаю) із включенням ключового слова з обмеженням. Що в основному каже компілятору, що в межах даного вказівника вказівник не перебуває. Крім того, C забезпечує належну арифметику покажчика, коли такі речі, як псевдонім, можуть бути дуже корисними з точки зору продуктивності та розподілу ресурсів. Хоча я думаю, що новіша версія FORTRAN дозволяє використовувати "належні" покажчики.

Для сучасних реалізацій C загалом перевершує FORTRAN (хоча це теж дуже швидко).

http://benchmarksgame.alioth.debian.org/u64q/fortran.html

Редагувати:

Справедлива критика цього, здається, полягає в тому, що тестування може бути упередженим. Ось ще одне джерело (по відношенню до С), яке дає результат у більш контексті:

http://julialang.org/benchmarks/

Ви можете бачити, що C зазвичай перевершує Фортран у більшості випадків (знову див. Критику нижче, що стосується і тут); як заявили інші, бенчмаркінг - це неточна наука, яку можна легко завантажити, щоб віддати перевагу одній мові перед іншими. Але це ставить у контекст того, як Fortran та C мають схожі показники.


3
Нерозумно було б вірити що-небудь про Фортран з поста, який передбачає, що це все-таки FORTRAN. Це змінилося більше 25 років тому. Ці тести не можуть порівнювати мови, оскільки вони використовують компілятори різних постачальників, хоча і Intel, і GCC мають компілятори як для C, так і для Fortran. Тому ці порівняння марні.
Володимир Ф

2

Fortran дуже зручно обробляти масиви, особливо багатовимірні масиви. Нарізання елементів багатовимірного масиву у Fortran може бути набагато простіше, ніж у C / C ++. Тепер у C ++ є бібліотеки, які можуть виконувати цю роботу, як-от Boost або Eigen, але вони все-таки зовнішні бібліотеки. У Fortran ці функції є сутнісними.

Чи буде Фортран швидшим чи зручнішим для розвитку, в основному залежить від роботи, яку потрібно закінчити. Як людина з наукових обчислень для геофізики, я зробив більшу частину обчислень у Фортран (я маю на увазі сучасний Фортран,> = F90).


1
А також, чи буде Fortran швидше, також залежить від компілятора, який ви використовуєте (це має значення!), Для обчислювальних завдань, чи застосовуєте ви відповідну паралелізацію до коду та те, як написаний ваш код.
Кай

1

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

EDIT: Інші люди, такі як @Nils, підкреслили хорошу думку про різницю у використанні покажчиків на C та можливість їх вивільнення, що, можливо, робить найбільш наївні реалізації повільнішими в C. Однак, у C99 є способи вирішити це. через прапорці оптимізації компілятора та / або в тому, як насправді написано С. Це добре висвітлено у відповіді @Nils та наступних коментарях, які випливають з його відповіді.


Це звучить як тест алгоритму на еталоні. На що потрібно менше часу, FORTRAN або C? Мені це не звучить суб’єктивно. Можливо, мені чогось не вистачає.
С.Лотт

1
Не згоден. Ви порівнюєте компілятори, а не мови. Я думаю, що первісне питання полягає в тому, чи є щось про МОВУ, що робить її по суті кращою. Інші відповіді тут натрапляють на деякі найтонші сумнівні відмінності, але я думаю, що ми найбільше згодні, що вони в шумі.
Високий Джефф

Це не O (n) аналіз алгоритмів. Це продуктивність. Не бачите, як ефективність може бути гіпотетичною незалежною від реалізації концепцією. Здогадайтесь, я щось пропускаю.
С.Лотт

1
-1: "Немає нічого про Фортран над C, що робить його по суті швидшим або кращим, ніж C". Помилка, ні.
Джон Харроп

0

Більшість публікацій вже є переконливими аргументами, тож я просто додам промовисті 2 центи для іншого аспекту.

Бути fortran швидше чи повільніше з точки зору процесорної потужності, врешті-решт, може мати своє значення, але якщо для формування чогось у Fortran потрібно 5 разів більше часу, тому що:

  • їй не вистачає будь-якої гарної бібліотеки для завдань, відмінних від чистих стискань чисел
  • у ньому немає будь-якого гідного інструменту для документації та тестування одиниць
  • це мова з дуже низькою експресивністю, що збільшує кількість рядків коду.
  • він має дуже погану обробку струн
  • у неї є безліч питань серед різних компіляторів та архітектур, що зводить вас з розуму.
  • у нього дуже погана стратегія вводу-виводу (ЧИТАТИ / ЗАПИСИТИ послідовні файли. Так, файли з випадковим доступом існують, але ви коли-небудь бачили їх використання?)
  • це не заохочує належних практик розвитку, модуляризації.
  • ефективна відсутність повністю стандартного, повністю сумісного компілятора відкритих джерел (і gfortran, і g95 не підтримують все)
  • дуже погана взаємодія з C (маніпулювання: одна підкреслення, дві підкреслення, відсутність підкреслення, загалом одна підкреслення, але дві, якщо є ще одна підкреслення. І просто не дозволяйте заглиблюватися в загальні блоки ...)

Тоді питання не має значення. Якщо щось відбувається повільно, більшу частину часу ви не можете покращити це за визначеною межею. Якщо ви хочете чогось швидшого, змініть алгоритм. Зрештою, комп'ютерний час коштує дешево. Людського часу немає. Цінуйте вибір, який скорочує людський час. Якщо це збільшує час роботи за комп’ютером, це все одно вигідно.


3
Незважаючи на те, що хоча ви піднімаєте цікаві моменти, що додають до обговорення переваг / недоліків у порівнянні з іншими мовами (з якими я не повністю згоден), це насправді не відповідає на питання ...
steabert

@steabert: насправді я сказавI will just add the proverbial 2 cents to a different aspect
Стефано Борині

1
+1 від мене за певну відповідь. Як ви вже говорили, Fortran може бути швидшим у виконанні рідкісних завдань (особисто не бачив). Але кількість часу, який ви витрачаєте на підтримку нездійсненної мови, позбавляється будь-якої можливої ​​переваги.
Андре Бергнер

10
-1. Ви, здається, думаєте про Фортран з точки зору F77. Це було витіснене F90, F95, F03 та F08.
Кайл Канос

4
Захищений, оскільки він говорить виключно про одну сторону компромісу. Швидкість розробки може мати значення для більшості загальних програм, але це не робить його єдиним дійсним компромісом. Програмісти Fortran часто є вченими / інженерами, які цінують простоту мови (переклад FORmula надзвичайно легко вивчити та оволодіти. C / C ++ ні ), чудові бібліотеки (часто використовуються з інших мов) та швидкість (наприклад, симуляції погоди які тривають дні у Фортран, але місяці, якщо вони написані повністю іншими мовами).
BraveNewCurrency

-3

Фортран традиційно не встановлює параметри, такі як -fp: строгі (що ifort вимагає, щоб включити деякі функції в USE IEEE_arithmetic, що є частиною стандарту f2003). Intel C ++ також не встановлює -fp: строгий як за замовчуванням, але це потрібно для обробки ERRNO, наприклад, та інших компіляторів C ++ не робить зручним вимикати ERRNO або отримувати оптимізації, такі як скорочення simd. gcc та g ++ вимагають, щоб я створив Makefile, щоб уникнути використання небезпечної комбінації -O3 -ffast-math -fopenmp -march = native. Крім цих питань, це питання щодо відносної продуктивності стає більш вибагливим і залежить від місцевих правил щодо вибору компіляторів та варіантів.


Останні оновлення gcc виправили проблему з комбінацією Openmp та швидкої математики.
tim18

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