Легче ли оптимизировать Fortran, чем C, для тяжелых вычислений?


410

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

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


53
Нереально субъективно из ответов, приведенных ниже. Правильный заголовок: «Существуют ли какие-то основополагающие архитектурные причины, по которым компилятор Фортрана МОЖЕТ производить код с большей оптимизацией, чем компилятор C», но это просто придирчивость.
Мартин Беккет,

3
Думаю, заглавный вопрос не столько субъективен, сколько недоразумен. Более подробный вопрос не субъективен.
jfm3

1
Я не думаю, что кто-то многому научился бы из этого, кроме ответов «Да» и «Нет» одновременно, и они варьируются в зависимости от компилятора, источника, процессора, расположения памяти и т. Д. И т. Д. И т. Д. Yawn.
user7116 28.09.08

1
Я не думаю, что вопрос или ответы субъективны. Но если вы думаете, что этот флаг кому-то помогает, я в порядке.
Quinmars

2
@sixlettervariables, хотя вы и я уже знаем ответ, это вопрос, который возникает у большинства людей в начале их карьеры, и важно понять ответ. Вместо того, чтобы публиковать отрицательный комментарий, почему бы не найти ответ, с которым вы согласны, и дать +1
MarkJ

Ответы:


447

Языки имеют похожие наборы функций. Разница в производительности объясняется тем, что Fortran говорит, что использование псевдонимов недопустимо, если только не используется оператор EQUIVALENCE. Любой код, имеющий псевдонимы, не является допустимым Fortran, но это зависит от программиста, а не от компилятора, чтобы обнаружить эти ошибки. Таким образом, компиляторы Fortran игнорируют возможные псевдонимы указателей памяти и позволяют им генерировать более эффективный код. Взгляните на этот маленький пример в C:

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;
    }
}

Эта функция будет работать медленнее, чем аналог Фортрана после оптимизации. Почему так? Если вы записываете значения в выходной массив, вы можете изменить значения матрицы. В конце концов, указатели могут перекрываться и указывать на один и тот же кусок памяти (включая intуказатель!). Компилятор C вынужден перезагружать четыре значения матрицы из памяти для всех вычислений.

В 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
Во-вторых, вам не нужно использовать переключатель компилятора no alias. Просто напишите код, чтобы нагрузки, основанные на указателе, сначала были назначены в автоматическую переменную, а затем оттуда работали с автоматикой. Он будет выглядеть более многословно, но компилятором он будет идеально оптимизирован.
Высокий Джефф

33
Хорошим примером является простое существование memcpy () и memmove (). В отличие от memcpy (), memmove () справляется с перекрывающимися областями, поэтому memcpy () может быть быстрее чем memmove (). Эта проблема была достаточной причиной для включения двух функций вместо одной в стандартную библиотеку.
JFS

12
Я думаю, что в этом и был смысл Себастьяна - из-за сложности / гибкости обработки памяти C даже такая простая вещь, как перемещение памяти, является сложной задачей.
Мартин Беккет

3
Ваш call transformпример не имеет большого смысла.
Владимир Ф

163

Да, в 1980 году; в 2008? зависит

Когда я начал профессионально программировать, доминирование в скорости на Фортране было под вопросом. Я помню, как читал об этом в «Докторе Доббсе» и рассказывал старшим программистам о статье - они смеялись.

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

Вплоть до и включая Fortran 77 вопросы разработки языка были в центре внимания оптимизации. Из-за состояния теории и технологии компилятора это часто означало ограничение возможностей и возможностей, чтобы дать компилятору наилучший шанс для оптимизации кода. Хорошая аналогия - думать о Fortran 77 как о профессиональной гоночной машине, которая жертвует характеристиками ради скорости. В наши дни компиляторы стали лучше на всех языках, а функции для повышения производительности программирования более ценны. Тем не менее, есть еще места, где люди в основном заинтересованы в скорости в научных вычислениях; эти люди, скорее всего, унаследовали код, обучение и культуру от людей, которые сами были программистами на Фортране.

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

Прекрасным местом для изучения истории и культуры Фортрана является Википедия. Запись в Fortran Wikipedia великолепна, и я очень ценю тех, кто потратил время и силы, чтобы сделать ее полезной для сообщества 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процедуры , и т.д. дальнейшей помощи для оптимизации кода. По этой простой причине даже указатели на Фортране не так гибки, как С.

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

Да, Fortran может быть быстрым просто потому, что компиляторы могут оптимизировать / распараллелить его лучше, чем C / C ++. Но опять же, как и все в жизни, есть хорошие компиляторы и плохие компиляторы.



1
forallКонструкция устарела , потому что составители не смогли оптимизировать код хорошо. Замена есть do concurrent. Кроме того, код sqrt(sum(x**2))выглядит неэффективно, потому что компилятор, вероятно, создает весь вектор x**2. Я думаю, что цикл лучше, но, несомненно, лучше вызывать встроенную norm2функцию.
А. Хеннинк

39

Забавно, что здесь много ответов от незнания языков. Это особенно верно для программистов на C / C ++, которые открыли старый код FORTRAN 77 и обсудили его слабые стороны.

Я полагаю, что проблема скорости - это в основном вопрос между C / C ++ и Fortran. В огромном коде это всегда зависит от программиста. Есть некоторые особенности языка, которые Фортран превосходит, и некоторые функции, которые делает С. Таким образом, в 2011 году никто не может сказать, какой из них быстрее.

Что касается самого языка, Fortran в настоящее время поддерживает функции Full OOP и полностью обратно совместим. Я использовал Fortran 2003 полностью, и я бы сказал, что использовать его было просто восхитительно. В некоторых аспектах Fortran 2003 все еще отстает от C ++, но давайте посмотрим на его использование. Fortran в основном используется для численных вычислений, и никто не использует причудливые функции C ++ ООП по соображениям скорости. В высокопроизводительных вычислениях C ++ практически некуда деваться (взгляните на стандарт MPI, и вы увидите, что C ++ устарел!).

В настоящее время вы можете просто заниматься программированием на разных языках с помощью Fortran и C / C ++. Есть даже интерфейсы для GTK + в Фортране. Есть бесплатные компиляторы (gfortran, g95) и много отличных коммерческих.


8
Не могли бы вы добавить источник, конкретный опыт или научный институт / агентство высокопроизводительных вычислений, которое либо уходит от C ++ для будущих проектов, либо переписывает проекты C ++ на другой язык. Я спрашиваю только потому, что знаю как минимум два научных учреждения, Sandia и CERN, которые интенсивно используют c ++ для своего высокопроизводительного моделирования. Кроме того, Сандия перевела одно из своих программ для моделирования (LAMMPS) с Fortran на C ++, добавив ряд удивительных улучшений.
Захария Крауса

7
LAMMPS написан на чрезвычайно простом C ++, который не использует большинство современных возможностей языка. Он представляет C ++, который программисты на Фортране, знающие C, пишут после изучения C ++ 98. Это не значит, что LAMMPS написан плохо, просто это не тот пример, который вы хотели бы привести, выступая за C ++ в HPC.
Джефф

30

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

  • ЧИСТЫЕ и ЭЛЕМЕНТНЫЕ ключевые слова о функциях. Это функции, которые не имеют побочных эффектов. Это позволяет выполнять оптимизацию в определенных случаях, когда компилятор знает, что одна и та же функция будет вызываться с одинаковыми значениями. Примечание: GCC реализует «чистый» как расширение языка. Другие компиляторы могут также. Межмодульный анализ также может выполнить эту оптимизацию, но это сложно.

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

  • Встроенный комплексный тип. Теоретически это может позволить компилятору переупорядочить или исключить определенные инструкции в определенных случаях, но, скорее всего, вы увидите то же преимущество с struct {double re, im; }; идиома, используемая в C. Это ускоряет разработку, хотя операторы работают со сложными типами в фортране.


1
msgstr "но, скорее всего, вы увидите то же преимущество с структурой, { double re, im; };используемой в C". Компиляторы Си, скорее всего, будут возвращать эту структуру в виде sret с выделением пространства стеком вызывающей стороны, передавая указатель вызываемому объекту, который его заполняет. Это в несколько раз медленнее, чем возвращение нескольких значений в регистрах, как это делает компилятор Фортрана. Обратите внимание, что C99 исправил это в особом случае complex.
Джон Харроп

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

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

28

Я думаю, что ключевым моментом в пользу Fortran является то, что это язык, немного более подходящий для выражения математики на основе векторов и массивов. Упомянутая выше проблема анализа указателей является реальной на практике, поскольку переносимый код не может предположить, что вы можете что-то сказать компилятору. ВСЕГДА преимущество в вычислениях выражений заключается в том, что они ближе к тому, как выглядит домен. У C на самом деле нет массивов, если присмотреться, просто что-то вроде этого. Фортран имеет настоящие массивы. Что облегчает компиляцию для определенных типов алгоритмов, особенно для параллельных машин.

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


25

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

То, что вы действительно должны спросить, это «код скомпилирован с компилятором Fortran X быстрее, чем эквивалентный код скомпилирован с компилятором C Y?» Ответ на этот вопрос, конечно, зависит от того, какие два компилятора вы выберете.

Другой вопрос, который можно было бы задать, звучит так: «Учитывая тот же объем усилий, приложенных для оптимизации их компиляторов, какой компилятор будет производить более быстрый код?» Ответом на этот вопрос будет Фортран . Компиляторы Fortran имеют ряд преимуществ:

  • Fortran пришлось конкурировать с Assembly в тот день, когда некоторые пообещали никогда не использовать компиляторы, поэтому он был разработан для скорости. C был разработан, чтобы быть гибким.
  • Ниша Фортрана была хрустом номера. В этом домене код никогда не бывает достаточно быстрым. Так что всегда было большое давление, чтобы язык был эффективным.
  • Большая часть исследований по оптимизации компилятора проводится людьми, заинтересованными в ускорении обработки кода на Fortran, поэтому оптимизация кода на Fortran является гораздо более известной проблемой, чем оптимизация любого другого скомпилированного языка, и сначала в компиляторах Fortran появляются новые инновации.
  • Biggie : C поощряет гораздо большее использование указателей, чем Fortran. Это резко увеличивает потенциальную область действия любого элемента данных в программе на C, что значительно затрудняет их оптимизацию. Обратите внимание, что Ada также намного лучше, чем C в этой области, и является гораздо более современным языком OO, чем обычно встречающийся Fortran77. Если вы хотите OO-язык, который может генерировать более быстрый код, чем C, это вариант для вас.
  • Из-за своей узкой ниши заказчики компиляторов Fortran, как правило, больше заботятся об оптимизации, чем заказчики компиляторов Си.

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


4
Согласен. И позвольте мне добавить, что когда в конце 50-х - начале 60-х был представлен Fortran (это был первый язык высокого уровня), многие скептически относились к его эффективности. Поэтому его разработчики должны были доказать, что Fortran может быть эффективным и полезным, и начали «оптимизировать его до смерти», чтобы доказать свою точку зрения. C пришел гораздо позже (в начале и середине 70-х) и ему было нечего доказывать, так сказать. Но к этому времени было написано много кода на фортранском языке, поэтому научное сообщество придерживалось его и до сих пор делает. Я не программирую на Фортране, но научился ссылаться на вызовы Фортрана из C ++.
Olumide

3
Исследования по оптимизации компилятора были более разнообразными, чем вы думаете. Например, история реализаций LISP полна успехов в обработке чисел быстрее, чем Fortran (который остается претендентом по умолчанию на вызов). Кроме того, огромная часть оптимизации компилятора была нацелена на промежуточные представления компилятора, что означает, что, за исключением различий в семантике (например, псевдонимы), они применяются к любому языку программирования данного класса.
Нигде человек

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

@Praxeolitic - Это совершенно правильно (вот почему я рад, что не сказал ничего подобного).
TED

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

22

Есть еще одна вещь, где Фортран отличается от С - и потенциально быстрее. У Fortran есть лучшие правила оптимизации, чем у C. В Fortran порядок вычисления выражений не определен, что позволяет компилятору оптимизировать его - если кто-то хочет форсировать определенный порядок, нужно использовать круглые скобки. В C порядок намного строже, но с опциями «-fast» они более смягчены и «(...)» также игнорируются. Я думаю, что у Фортрана есть путь, который приятно лежит посередине. (Ну, IEEE усложняет работу, так как некоторые изменения порядка оценки требуют, чтобы не происходило переполнения, что либо должно быть проигнорировано, либо затрудняет оценку).

Другая область более разумных правил - комплексные числа. Мало того, что до C 99 у них были они, также правила управляют ими лучше в Фортране; Поскольку библиотека gfortran на Фортране частично написана на C, но реализует семантику на Fortran, GCC получила опцию (которую также можно использовать с «обычными» программами на C):

-fcx-fortran-rules Комплексное умножение и деление следуют правилам Фортрана. Уменьшение диапазона выполняется как часть сложного деления, но нет проверки, является ли результат сложного умножения или деления «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 как бессмысленную.
Суперкат

14

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

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

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


11
Почти обновил это. Проблема заключается в том, что Fortran действительно имеют некоторые преимущества , присущие. Тем не менее, вы совершенно уверены, что важнее всего обращать внимание на компилятор, а не на язык.
TED

14

Я сравниваю скорость Fortran, C и C ++ с классическим тестом Levine-Callahan-Dongarra от netlib. Мультиязычная версия с OpenMP http://sites.google.com/site/tprincesite/levine-callahan-dongarra-vectors C более уродливая, так как она началась с автоматического перевода, а также с определенными ограничениями и прагмами. компиляторы. C ++ - это просто C с шаблонами STL, где это применимо. На мой взгляд, STL представляет собой смешанный пакет с точки зрения того, улучшает ли он ремонтопригодность.

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

Компилятору C / C ++, который на данный момент наиболее широко используется, не хватает авто-векторизации, на которую сильно влияют эти тесты.

В связи с постом, который был опубликован непосредственно перед этим: есть несколько примеров, где в Фортране используются скобки для определения более быстрого или более точного порядка оценки. Известные компиляторы C не имеют возможности соблюдать скобки, не отключая более важные оптимизации.


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

12

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

Я не знаю, является ли это историческим фактом, но Фортран чувствует, что он построен так, чтобы быть параллельным / распределенным / векторизованным / каким бы многоядерным он ни был. И сегодня это в значительной степени «стандартная метрика», когда мы говорим о скорости: «она масштабируется?»

За чистоту процессора я люблю Фортран. Для всего, что связано с IO, мне легче работать с C. (в любом случае это сложно в любом случае).

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

Мой умеренно объективный ответ таков: если вы знаете оба языка одинаково / плохо, то я думаю, что Fortran быстрее, потому что мне легче писать параллельный / распределенный код на Fortran, чем на C. (как только вы поняли, что вы можете писать "freeform" fortran и не просто строгий код F77)

Вот второй ответ для тех, кто хочет меня понизить, потому что им не нравится первый ответ: оба языка имеют функции, необходимые для написания высокопроизводительного кода. Таким образом, это зависит от алгоритма, который вы реализуете (интенсивное использование процессора, интенсивное использование памяти), аппаратного обеспечения (одноядерный процессор, многоядерный распределительный суперкомпьютер, GPGPU, FPGA), ваших навыков и, в конечном счете, самого компилятора. И C, и Fortran имеют отличный компилятор. (Я серьезно удивлен тем, насколько продвинуты компиляторы Фортрана, но так же, как и компиляторы Си).

PS: я рад, что вы специально исключили библиотеки, потому что у меня есть много плохого, что можно сказать о библиотеках Fortran GUI. :)


11

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


10

Любые различия в скорости между Fortran и C будут скорее функцией оптимизации компилятора и базовой математической библиотеки, используемой конкретным компилятором. В Fortran нет ничего, что могло бы сделать его быстрее, чем C.

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


@ Скотт Клоусон: ты получил -1, и я не знаю почему. +1 я бы исправил это. Однако следует учитывать, что Фортран существует дольше, чем многие наши родители. Много времени потрачено на оптимизацию вывода компилятора: D
user7116

Согласен. Я только что опубликовал очень похожий ответ параллельно.
Высокий Джефф

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

1
@Kluge: «В Fortran нет ничего, что могло бы сделать его быстрее, чем C». Псевдонимы указателей, возвращающие составные значения в регистрах, встроенные высокоуровневые числовые конструкции ...
Джон Харроп

9

Я не слышал, чтобы Фортан был значительно быстрее, чем С, но вполне возможно, что в некоторых случаях он будет быстрее. И ключ не в языковых особенностях, которые присутствуют, а в тех, которые (обычно) отсутствуют.

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

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

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

Компилятор должен работать в предположении, что d и s могут быть перекрывающимися массивами. Таким образом, он не может выполнить оптимизацию, которая выдала бы другие результаты, когда массивы перекрываются. Как и следовало ожидать, это значительно ограничивает виды оптимизации, которые могут быть выполнены.

[Следует отметить, что в C99 есть ключевое слово restrict, которое явно указывает компиляторам, что указатели не перекрываются. Также обратите внимание, что у Фортрана тоже есть указатели, семантика которых отличается от семантики C, но указатели не являются повсеместными, как в C.]

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


9

Быстро и просто: оба одинаково быстры, но Фортран проще. То, что действительно быстрее в конечном итоге, зависит от алгоритма, но в любом случае разница в скорости отсутствует. Это то, что я узнал на семинаре по Fortran в высокопроизводительном вычислительном центре Штутгарда, Германия, в 2015 году. Я работаю с Fortran и C и разделяю это мнение.

Объяснение:

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

Фортран был разработан для научного программирования. По этой причине он поддерживает быстрое написание синтаксиса кода, так как это является основной целью Fortran. В отличие от общественного мнения, Фортран не является устаревшим языком программирования. Его последний стандарт - 2010, и новые компиляторы публикуются на регулярной основе, так как наиболее высокопроизводительный код написан на Фортране. Fortran также поддерживает современные функции в качестве директив компилятора (на языке C).

Пример: мы хотим дать большую структуру в качестве входного аргумента функции (fortran: подпрограмма). Внутри функции аргумент не изменяется.

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

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


Можете ли вы написать собственное параллельное приложение на C (т.е. без вызова каких-либо библиотек?). Можете ли вы написать собственное параллельное приложение на Фортране? Да, несколькими разными способами. Ergo, Fortran "быстрее". Хотя, честно говоря, в 2010 году, когда вы написали свой комментарий, поддержка параллельных операций и функций совместного использования массивов в Fortran, вероятно, была не так широко распространена, как сейчас.
Мали Реморкер

@MaliRemorker Он написал это в 2016 году, а не в 2010 году.
Ковальски

Накладные расходы на создание параллельных процессов, на мой взгляд, не самый важный фактор для языка программирования, называемого «быстрым». Более уместны практические соображения, такие как неисполнение кода. Так что это ничего не поможет, если вы экономите время один раз (при создании параллельного процесса), а потом тратите его на несколько ядер. Термин «быстрый» также должен учитывать непараллельные коды. По этой причине я не вижу аргумента против моей точки зрения. Может быть, ваш комментарий был назван независимым ответом?
Маркус Дучке

8

Обычно FORTRAN работает медленнее, чем C. C может использовать указатели аппаратного уровня, позволяющие программисту оптимизировать работу вручную. ФОРТРАН (в большинстве случаев) не имеет доступа к аппаратному взлому адресации памяти. (VAX FORTRAN - другая история.) Я использовал FORTRAN и выключал его с 70-х годов. (В самом деле.)

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

В C вы должны управлять своими собственными потоками и тщательно разрабатывать свой алгоритм для многопроцессорной обработки, а затем использовать кучу вызовов API, чтобы убедиться в правильности параллелизма.

В FORTRAN вам нужно только тщательно разработать свой алгоритм для многопроцессорной обработки. Компилятор и среда выполнения могут обработать все остальное за вас.

Вы можете прочитать немного о High Performance Fortran , но вы найдете много мертвых ссылок. Вам лучше прочитать о параллельном программировании (например, OpenMP.org ) и о том, как это поддерживает FORTRAN.


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

2
@ Грег Роджерс: Вы должны будете решать вашу проблему с людьми из 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 Compiler, потому что вы можете получить его в LINUX и Windows, и вы можете использовать VS в качестве IDE, если вы ищете дешевый тугой компилятор вы всегда можете передать на OpenWatcom.

Подробнее об этом: http://ed-thelen.org/1401Project/1401-IBM-Systems-Journal-FORTRAN.html


3

Fortran имеет лучшие процедуры ввода / вывода, например, подразумеваемое средство do дает гибкость, с которой стандартная библиотека C не может сравниться.

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


1
У вас есть тесты, которые показывают, что Фортран побеждает C за ввод-вывод?
Джефф

3

Используя современные стандарты и компилятор, нет!

Некоторые из них предположили, что FORTRAN работает быстрее, потому что компилятору не нужно беспокоиться о псевдонимах (и, следовательно, он может делать больше предположений при оптимизации). Тем не менее, это было решено в C начиная со стандарта C99 (я думаю) с включением ключевого слова restrict. Что в основном говорит компилятору, что в заданной области указатель не является псевдонимом. Кроме того, C обеспечивает правильную арифметику указателей, где такие вещи, как псевдонимы, могут быть очень полезны с точки зрения производительности и распределения ресурсов. Хотя я думаю, что более поздняя версия FORTRAN позволяет использовать «правильные» указатели.

В современных реализациях C вообще превосходит FORTRAN (хотя он тоже очень быстрый).

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

РЕДАКТИРОВАТЬ:

Справедливая критика этого, похоже, заключается в том, что сравнительный анализ может быть предвзятым. Вот еще один источник (относительно C), который помещает результат в больший контекст:

http://julialang.org/benchmarks/

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


4
Было бы глупо поверить во что-нибудь о Фортране из поста, который предполагает, что это все еще Фортран. Это изменилось более 25 лет назад. Эти тесты не могут сравнивать языки, потому что они используют компиляторы разных производителей, хотя и у Intel, и у GCC есть компиляторы для C и Fortran. Поэтому эти сравнения бесполезны.
Владимир Ф

2

Fortran может очень удобно обрабатывать массивы, особенно многомерные. Нарезка элементов многомерного массива в Fortran может быть намного проще, чем в C / C ++. C ++ теперь имеет библиотеки, которые могут выполнять эту работу, такие как Boost или Eigen, но они все-таки внешние библиотеки. В Фортране эти функции присущи.

Быстрее или удобнее ли разрабатывать Fortran, зависит от того, какую работу вы должны выполнить. Как научный специалист по геофизике, я делал большинство вычислений на Фортране (я имею в виду современный Фортран,> = F90).


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

1

Это более чем субъективно, потому что это влияет на качество компиляторов и тому подобное больше всего на свете. Однако, чтобы более прямо ответить на ваш вопрос, говоря с точки зрения языка / компилятора, в Fortran over C нет ничего, что сделало бы его по своей природе быстрее или лучше, чем C. Если вы выполняете тяжелые математические операции, все сводится к качество компилятора, умение программиста на каждом языке и встроенные библиотеки поддержки математики, которые поддерживают эти операции, чтобы в конечном итоге определить, что будет быстрее для данной реализации.

РЕДАКТИРОВАТЬ: Другие люди, такие как @Nils, подняли хороший вопрос о разнице в использовании указателей в C и возможности псевдонимов, что, возможно, делает наиболее наивные реализации медленнее в C. Однако, есть способы справиться с этим в C99 через флаги оптимизации компилятора и / или в том, как на самом деле написан Си. Это хорошо освещено в ответе @Nils и последующих комментариях к его ответу.


Это звучит как эталонный тест алгоритма. Что занимает меньше времени, Фортран или С? Не звучит субъективно для меня. Возможно, я что-то упустил.
S.Lott

1
Не согласен. Вы сравниваете компиляторы, а не языки. Я думаю, что первоначальный вопрос заключается в том, есть ли что-то в ЯЗЫКЕ, что делает его по сути лучше. Другие ответы здесь входят в некоторые тонкие сомнительные различия, но я думаю, что мы больше всего согласны, что они в шуме.
Высокий Джефф

Это не O (n) анализ алгоритмов. Это производительность. Не понимаю, как производительность может быть гипотетической концепцией, независимой от реализации. Думаю, я что-то упустил.
С.Лотт

1
-1: «В Fortran over C нет ничего, что могло бы сделать его быстрее или лучше, чем C». Нет, нет
Джон Харроп

0

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

Быть Fortran быстрее или медленнее с точки зрения вычислительной мощности в конечном итоге может иметь значение, но если для разработки чего-то в Fortran требуется в 5 раз больше времени, потому что:

  • ему не хватает хорошей библиотеки для задач, отличных от перебора чисел
  • не хватает достойного инструмента для документации и модульного тестирования
  • это язык с очень низкой выразительностью, который взлетает до количества строк кода.
  • у него очень плохая обработка строк
  • у него огромное количество проблем среди разных компиляторов и архитектур, сводящих вас с ума.
  • у него очень плохая стратегия ввода-вывода (READ / WRITE последовательных файлов. Да, файлы с произвольным доступом существуют, но вы когда-нибудь видели, чтобы они использовались?)
  • это не поощряет хорошие практики развития, модульность.
  • эффективное отсутствие полностью стандартного, полностью совместимого компилятора с открытым исходным кодом (и gfortran, и g95 не поддерживают все)
  • очень плохая совместимость с C (искажение: одно подчеркивание, два подчеркивания, без подчеркивания, в общем, одно подчеркивание, но два, если есть другое подчеркивание. и просто давайте не углубляться в ОБЩИЕ блоки ...)

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


3
не одобряется, потому что, хотя вы поднимаете интересные вопросы, которые дополняют обсуждение преимуществ / недостатков Fortrans по сравнению с другими языками (с которыми я не полностью согласен), на самом деле это не ответ на вопрос ...
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 TRANslation чрезвычайно прост в изучении и освоении. C / C ++ нет ), отличные библиотеки (часто используемые на других языках) и скорость (например, моделирование погоды это займет дни в Фортране, но месяцы, если написано полностью на других языках).
BraveNewCurrency

-3

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


Недавние обновления gcc исправили проблему с сочетанием Openmp и fast-math.
Тим18,

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