Время от времени я читаю, что Fortran быстрее C для тяжелых вычислений. Это действительно так? Должен признать, что я почти не знаю Фортран, но код на Фортране, который я видел до сих пор, не показал, что у языка есть функции, которых нет в Си.
Если это правда, скажите, пожалуйста, почему. Пожалуйста, не говорите мне, какие языки или библиотеки подходят для обработки чисел, я не собираюсь писать приложение или библиотеку для этого, мне просто любопытно.
Я думаю, что вопрос, связанный с заголовком, не столько субъективен, сколько недоразумен. Более подробный вопрос не субъективен.
Я не думаю, что кто-то многому научится из этого, кроме того, что ответ - «Да» и «Нет» одновременно, и зависит от компилятора, источника, процессора, разметки памяти и т. д. И т. Д. Зевок.
Не думаю, что вопрос или ответы субъективны. Но если вы думаете, что этот флаг кому-то помогает, меня это устраивает.
Вопрос слишком общий (Fortran быстрее, чем C в какой проблемной области?), Но я не думаю, что следующее обсуждение является субъективным. Мы можем создать небольшой код, подтверждающий / опровергающий любое утверждение, если проблема достаточно конкретна.
Почему новички всегда спрашивают, быстрее ли это, чем вопросы такого типа? Половину времени они беспокоятся о бессмысленных функциях, которые выполняют несколько циклов через час.
@sixlettervariables, хотя мы с вами уже знаем ответ, это вопрос, который возникает у большинства людей в начале их карьеры, и важно понять ответ. Вместо того, чтобы оставлять пренебрежительный комментарий, почему бы не найти ответ, с которым вы согласны, и поставить +1
@MarkJ: хороший момент, я проголосовал за закрытие как не конструктивный.
Обратите внимание, что вам не нужно писать свою программу на Fortran, если все, что вы хотите сделать, это вызвать некоторые библиотеки Fortran. Можно легко вызвать код Fortran из C, все, о чем вам нужно помнить, это изменение имени, передача каждой переменной по ссылке и разный порядок матриц.
Верно. Кроме того, струны немного странные.
Можно добавить романтический вид (как программист Фортрана). В то время мы кодировали для чисел, а не для приложений в современном виде. Мы знали, потому что могли, отображение памяти любой матрицы, поэтому мы могли использовать обычные и имитирующие указатели C. И чтобы ответить на вопрос: да, в то время у вас были компиляторы, оптимизированные для fortran. Но менее романтично: поработайте на любом другом языке программирования.
На современном ЦП с предсказанием ветвлений, иерархической памятью и длинными конвейерами ответ однозначно отрицательный. Код C имеет тенденцию быть быстрее, чем Фортран, даже для числовой работы. Но есть и другие причины выбрать Fortran: C - полупортативный ассемблер высокого уровня. Фортран - это язык высокого уровня, который очень переносим, удобочитаем и легче отлаживать. Он обеспечивает высокую производительность с меньшими усилиями и намного проще в использовании, чем C. Но быстрее? Не в 2015 году. Проблема псевдонима указателя в C решена с помощью современного дизайна процессора и компиляторов C. Не так больно, как в 1980 году.
Фортран - это кувалда, он хорошо справляется с некоторыми задачами. C - швейцарский армейский нож. Если я хочу как можно быстрее получить доступ к алгоритмам с четырехъядерной точностью, распределенным / параллельным функциям, функциям blas, linpack или dsp, не беспокоясь о нулевых указателях и указателях на указатели на указатели, победит fortran. Даже библиотеки, лежащие в основе числовой обработки Matlab, по-прежнему используют код fortran.
Я совсем не эксперт в этом вопросе (сверхнизкий уровень - т.е. уровень регистров - оптимизация) и нашел ответы очень интересными.
... продолжение! ... Но хотя я уверен, что когда-то это, должно быть, было предметом страстных дебатов, сегодня это вызывает у меня очень мало актуальности, поскольку современный аппаратный ландшафт сильно отличается. В настоящее время доступность языков, специфичных для GPU / APU, таких как OpenCL и CUDA, ставит вопрос о том, C или FORTRAN быстрее, спорным. Ни один из них не является самым быстрым языком для обработки чисел с коэффициентом от 10 до 100+ просто потому, что они не работают на оборудовании GPU / APU.





Любые различия в скорости между Fortran и C будут больше зависеть от оптимизации компилятора и базовой математической библиотеки, используемой конкретным компилятором. В Fortran нет ничего такого, что могло бы сделать его быстрее, чем C.
В любом случае хороший программист может написать Фортран на любом языке.
@ Скотт Клоусон: ты получил -1, и я не знаю почему. +1, чтобы исправить это. Однако следует принять во внимание то, что Фортран существует дольше, чем многие наши родители. Много времени потрачено на оптимизацию вывода компилятора: D
Я согласен. Я только что опубликовал очень похожий ответ параллельно.
Проблема псевдонима указателя в C была поднята другими, но есть несколько методов, которые программист может использовать в современных компиляторах, чтобы справиться с этим, поэтому я все еще согласен.
@Kluge: «В Fortran нет ничего такого, что могло бы сделать его быстрее, чем C». Псевдонимы указателей, возвращение составных значений в регистрах, встроенные числовые конструкции более высокого уровня ...
Это более чем несколько субъективно, потому что больше всего влияет на качество компиляторов и тому подобное. Однако, чтобы более прямо ответить на ваш вопрос, говоря с точки зрения языка / компилятора, в Fortran нет ничего, что могло бы сделать его по своей сути быстрее или лучше, чем C.Если вы выполняете тяжелые математические операции, все сводится к качество компилятора, навыки программиста на каждом языке и встроенные математические вспомогательные библиотеки, которые поддерживают эти операции, чтобы в конечном итоге определить, что будет быстрее для данной реализации.
Обновлено: другие люди, такие как @Nils, подняли хороший вопрос о разнице в использовании указателей в C и возможности сглаживания, что, возможно, замедляет самые наивные реализации в C. Однако есть способы справиться с этим в C99. , через флаги оптимизации компилятора и / или в том, как на самом деле написан C. Это хорошо освещено в ответе @Nils и последующих комментариях, которые следуют за его ответом.
Похоже на эталонный тест алгоритма. Что занимает меньше времени, FORTRAN или C? Мне это не кажется субъективным. Возможно, я что-то упускаю.
Не согласен. Вы сравниваете компиляторы, а не языки. Я думаю, что исходный вопрос заключается в том, есть ли что-нибудь в ЯЗЫКЕ, которое делает его лучше по сути. Другие ответы здесь касаются некоторых тонких сомнительных различий, но я думаю, что мы больше всего согласны с тем, что они находятся в шуме.
Это не O (n) анализ алгоритмов. Это производительность. Не понимаю, как производительность может быть гипотетической концепцией, не зависящей от реализации. Думаю, я что-то упускаю.
-1: «В Fortran нет ничего, что могло бы сделать его быстрее или лучше, чем C». Эээ нет.
У языков схожий набор функций. Разница в производительности происходит из-за того, что 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 с радостью компилируют без каких-либо предупреждений, но вносит ошибку, которая проявляется только в некоторых компиляторах, на некотором оборудовании и с некоторыми параметрами оптимизации.
Помимо ключевого слова restrict, у большинства компиляторов есть флаги оптимизации командной строки, чтобы заставить компилятор не беспокоиться о наложении имен. Поскольку фактическое использование псевдонимов встречается довольно редко, я считаю этот уровень оптимизации отправной точкой по умолчанию.
Кроме того, без флага или ключевого слова new в C просто назначайте операции на основе указателя через автоматическую переменную. Это намекает компилятору на то, что псевдонимы можно игнорировать, и, хотя это выглядит как больше кода, вы на самом деле получите максимально быстрый результат с помощью оптимизатора.
«редко» может быть, а может и не быть хорошей причиной появления нестабильных недетерминированных ошибок. Я видел это в случаях, когда функция используется для обработки данных на месте или вне его.
Все верно и верно, Джефф. Тем не менее, я не считаю безопасным переключатель "не допускать наложения имен". Он может настолько тонко нарушить код, унаследованный от других проектов, что я бы предпочел не использовать его. По этой причине я стал нацистом-ограничителем :-)
Другие члены команды, которые еще не имеют достаточного опыта, также подвергаются риску, если вы не применяете алиасинг. Они могут написать отличный код, который в своей работе полагается на псевдонимы.
Fortran также может автоматически разделять такие вычисления по нескольким ядрам / CPUS, потому что он знает, что части arry не могут перекрываться.
@mgb: с соответствующей разметкой для включения этих функций.
Что касается моего второго замечания, вам не нужно использовать переключатель компилятора без псевдонима. Просто напишите код, чтобы нагрузки на основе указателя сначала назначались автоматической переменной, а затем уже оттуда работали с автоматикой. Он будет выглядеть более подробным, но компилятор прекрасно его оптимизирует.
Джефф, я согласен с автоматическими переменными, и я считаю, что писать код таким образом тоже хорошая практика. Это не только намекает компилятору, но и дает понять, что вы также не предполагаете использование псевдонимов. Приятно иметь, если вам придется потрогать код через год после написания.
Мне нравятся такие дискуссии - большинство людей (в целом) не ценят тонкости в подобных вещах. Хороший обмен мыслями - спасибо!
Хорошим примером является простое существование memcpy () vs. memmove (). В отличие от memcpy (), memmove () справляется с перекрывающимися областями, поэтому memcpy () может быть быстрее, чем memmove (). Эта проблема была достаточной причиной для того, чтобы кто-то включил в стандартную библиотеку две функции вместо одной.
Memcpy () vs. Memmove () на самом деле НЕ хороший пример. Используются разные алгоритмы. memcpy () - более простой (тривиальный) алгоритм, ПОТОМУ ЧТО по определению предполагается, что области не перекрываются. memmove () должна выполнять больше проверок и более сложный порядок операций копирования, ПОТОМУ ЧТО области МОГУТ перекрываться.
Я думаю, что это была точка зрения Себастьяна - из-за сложности / гибкости обработки памяти C даже такая простая вещь, как перемещение памяти, является сложной задачей.
Я хочу скопировать массив в C, можно использовать как memcpy (), так и memmove (). Выбор зависит от контекста. А в Фортране такого выбора делать не приходится из-за более строгих правил алиасинга.
Я хотел бы увидеть некоторые эталонные доказательства того, что Fortran быстрее, чем C. Не думаю, что у вас есть какие-либо ссылки?
Вы не упомянули еще одну вещь в своем коде C, которая работает медленнее: условие выхода в версии C должно проверяться повторно на каждой итерации. В вашем примере это можно было бы оптимизировать, но это невозможно, если бы в цикле было что-то, потенциально изменяющее n (или i).
ted, если компилятор может выяснить, как вывести его за пределы цикла, ему разрешено это сделать, из-за правила as-if, независимо от того, изменено ли n или нет, не имеет значения
Чтобы быть наоборот, позвольте мне указать, что если подпрограмма A содержит цикл, а подпрограмма B вызывается внутри цикла, B, вероятно, берет большую часть циклов. Оптимизация цикла в A мало что вам даст.
Насколько я помню, ключевое слово EQUIVALENCE допускало некоторые виды перекрытий массивов. Повлияет ли это на алиасинг в программе fortran?
@MitchWheat: «Я хотел бы увидеть некоторые эталонные доказательства того, что Фортран быстрее, чем C. Не думаю, что у вас есть какие-либо ссылки?». Blitz ++ стремился достичь производительности C++ на уровне Fortran и провел множество тестов для их сравнения. На задачу «Последовательная чрезмерная релаксация» из набора тестов SciMark2 влияет алиасинг, и, следовательно, Java превосходит C и C++, так что вы можете попробовать ее и в Fortran.
Ваш пример с call transform не имеет особого смысла.
@VladimirF почему в этом нет особого смысла?
@NilsPipenbrinck, вероятно, потому, что фактические аргументы будут иметь псевдонимы, и поэтому он недействителен Фортран с неопределенным поведением. Нет смысла говорить «C безопаснее, потому что Fortran позволяет мне писать нестандартный код с неопределенным поведением». C с радостью позволит вам войти в страну нестандартного кода с неопределенным поведением.
matrix - is this so? Why? How to see that? And: Why is the * n passed as pointer?
Есть даже лучшая особенность: программист fortran думает fortran. Я помню, как думал о распределении памяти во время кодирования. Я помню, как я получал 10-кратный фактор оптимизации других кодов. Все это просто потому, что это старый прямой язык программирования.
@embert, массив matrix может перекрываться с массивом output. transform(arr, arr, arr, &n) - допустимый вызов функции, предполагающий, что массив arr достаточно велик.
Фортран имеет тот же набор функций, что и C? Действительно? Во-первых, какой Фортран? Текущие популярные стандарты Fortran (2003/2008) = сверхгибкий стандарт модулей, объектно-ориентированный подход (для тех, кому небезразлично), встроенная поддержка параллельного программирования (параллельное выполнение), встроенная поддержка распределенных вычислений (co-array fortran). Если вы начнете свою программу с нуля, будет намного проще написать параллельное числовое приложение. Кроме того, интерфейс с библиотеками C упрощается через модуль iso_c_binding.
Я не слышал, что Fortan значительно быстрее, чем C, но можно предположить, что в некоторых случаях он будет быстрее. И дело не в языковых функциях, которые присутствуют, а в тех, которые (обычно) отсутствуют.
Примером являются указатели C. Указатели C используются практически везде, но проблема с указателями заключается в том, что компилятор обычно не может определить, указывают ли они на разные части одного и того же массива.
Например, если вы написали подпрограмму strcpy, которая выглядела так:
strcpy(char *d, const char* s)
{
while(*d++ = *s++);
}
Компилятор должен работать в предположении, что d и s могут перекрывать массивы. Таким образом, он не может выполнить оптимизацию, которая дала бы разные результаты при перекрытии массивов. Как и следовало ожидать, это значительно ограничивает виды оптимизаций, которые могут быть выполнены.
[Я должен отметить, что в C99 есть ключевое слово restrict, которое явно сообщает компиляторам, что указатели не перекрываются. Также обратите внимание, что в Fortran тоже есть указатели с семантикой, отличной от семантики C, но указатели не являются повсеместными, как в C.]
Но, возвращаясь к проблеме C и Fortran, вполне возможно, что компилятор Fortran может выполнять некоторые оптимизации, которые могут быть невозможны для (прямо написанной) программы на C. Так что я не был бы слишком удивлен заявлением. Однако я действительно ожидаю, что разница в производительности будет не такой уж большой. [~ 5-10%]
Обычно FORTRAN медленнее, чем C. C может использовать указатели аппаратного уровня, позволяя программисту оптимизировать вручную. FORTRAN (в большинстве случаев) не имеет доступа к аппаратным взломам адресации памяти. (VAX FORTRAN - это отдельная история.) Я использовал FORTRAN время от времени с 70-х годов. (Действительно.)
Однако, начиная с 90-х годов, FORTRAN эволюционировал и стал включать в себя определенные языковые конструкции, которые можно оптимизировать в по сути параллельные алгоритмы, которые может действительно кричит на многоядерном процессоре. Например, автоматическая векторизация позволяет нескольким процессорам одновременно обрабатывать каждый элемент вектора данных. 16 процессоров - 16 векторных элементов - обработка занимает 1/16 часть времени.
В C вы должны управлять своими собственными потоками и тщательно разрабатывать свой алгоритм для многопроцессорной обработки, а затем использовать набор вызовов API, чтобы убедиться, что параллелизм происходит должным образом.
В FORTRAN вам нужно только тщательно разработать свой алгоритм для множественной обработки. Все остальное компилятор и среда выполнения могут сделать за вас.
Вы можете немного почитать о Высокопроизводительный Фортран, но вы найдете много мертвых ссылок. Вам лучше прочитать о параллельном программировании (например, OpenMP.org) и о том, как FORTRAN это поддерживает.
@ S.Lott: Я не мог себе представить, как ужасно должен выглядеть код C, чтобы работать так же хорошо, как просто написанный на Фортране, для большинства кодов, которые у нас есть ... а я программист на C. Вы получите лучшую производительность из более простого кода на Фортране. Не то чтобы мы с вами не смогли найти контрпримера. : D
Ни один компилятор не собирается распространять вычисление на 16 элементов вектора на 16 различных процессоров. Это было бы в сотни раз медленнее ...
@sixlettervariales: Ага. Фортран делает это хорошо. C делает еще кое-что хорошо.
@Greg Rogers: Вам придется обсудить свой вопрос с людьми, занимающимися векторизацией Fortran, а не со мной. Я просто сообщаю то, что прочитал. polyhedron.com/absoftlinux
-1 // «Обычно FORTRAN медленнее, чем C. Это верно почти для всего». Почему? // аргумент, основанный на простоте использования многопоточности в Fortran vs C, ничего не говорит о производительности.
@steabert: многопоточность существует только для повышения производительности. Я не уверен, почему вы возражаете против этого. Производительность во время выполнения зависит от многих, многих вещей. Сам по себе язык не имеет значения. Тем не мение. Использование указателей в C почти на аппаратном уровне позволяет C быть быстрее, чем Fortran.
@ S.Lott: «многопоточность существует только для повышения производительности». Эээ нет.
@ S.Lott: «Использование указателей в C почти на аппаратном уровне позволяет C быть быстрее, чем Fortran». Эээ нет
«Многопоточность существует только для повышения производительности» У нее не может быть другой цели на этой земле. Вместо того, чтобы публиковать глупые мнения, объясните, в чем состоит смысл многопоточности, которая не связана строго (и только) с производительностью.
Ссылка, которую вы предоставили, уже мертва. Хотите предоставить другой?
возможность работать с очень большими наборами данных - еще одна цель многопоточности
В языки Fortran и C нет ничего, что делало бы один быстрее другого для определенных целей. Есть особенности составители для каждого из этих языков, которые делают одни более подходящими для определенных задач, чем другие.
В течение многих лет существовали компиляторы Fortran, которые могли творить черную магию с вашими числовыми подпрограммами, делая многие важные вычисления безумно быстрыми. Современные компиляторы Си тоже не могли этого сделать. В результате на Фортране выросло количество отличных библиотек кода. Если вы хотите использовать эти хорошо протестированные, зрелые, замечательные библиотеки, вы можете использовать компилятор Fortran.
Мои неофициальные наблюдения показывают, что в наши дни люди кодируют свои тяжелые вычислительные материалы на любом старом языке, и если это требует времени, они находят время на каком-нибудь дешевом вычислительном кластере. Закон Мура делает всех нас дураками.
Есть несколько причин, по которым Фортран может быть быстрее. Однако количество, которое они имеют значение, настолько несущественно, или его можно обойти в любом случае, что это не должно иметь значения. Основная причина использования Fortran в настоящее время - поддержка или расширение унаследованных приложений.
Ключевые слова PURE и ELEMENTAL в функциях. Это функции, у которых нет побочных эффектов. Это позволяет проводить оптимизацию в определенных случаях, когда компилятор знает, что одна и та же функция будет вызываться с одинаковыми значениями. Примечание: GCC реализует «чистый» как расширение языка. Другие компиляторы тоже могут. Межмодульный анализ также может выполнять эту оптимизацию, но это сложно.
стандартный набор функций, которые работают с массивами, а не с отдельными элементами. Такие вещи, как sin (), log (), sqrt (), принимают массивы вместо скаляров. Это упрощает оптимизацию распорядка. Автоматическая векторизация дает те же преимущества в большинстве случаев, если эти функции являются встроенными или встроенными.
Встроенный комплексного типа. Теоретически это может позволить компилятору переупорядочивать или удалять определенные инструкции в определенных случаях, но, вероятно, вы увидите такое же преимущество с идиомой struct { double re; double im; };, используемой в C. Это ускоряет разработку, хотя операторы работают со сложными типами в Фортране.
"но, вероятно, вы увидите такое же преимущество с идиомой struct { double re, im; };, используемой в C". Компиляторы C, скорее всего, вернут эту структуру в форме sret с выделением пространства стеком вызывающего объекта, передав указатель вызываемому объекту, который его заполняет. Это в несколько раз медленнее, чем возврат нескольких значений в регистры, как это сделал бы компилятор Fortran. Обратите внимание, что C99 исправил это в частном случае complex.
Я не уверен, что согласен с вашей основной причиной. Мне лично нравится использовать fortran для тяжелого математического кода, где массивы и математические функции являются наиболее важной частью кода. Но я точно знаю, что во многих государственных учреждениях и банках продолжают использовать fortran для поддержки или расширения устаревшего кода. Я лично использовал fortran для расширения кода профессора, имеющего степень доктора философии. комитет написал.
Ваше утверждение, что «основная причина использования Fortran в настоящее время - поддержка или расширение унаследованных приложений», совершенно неверно. Мне еще предстоит увидеть какой-либо другой язык программирования, хотя бы отдаленно близкий к функциям, которые предоставляет Фортран, особенно для математических приложений. Вы уже назвали некоторые из них, такие как превосходная поддержка массивов, встроенная сложная арифметика, чистые или элементарные функции - и я мог бы назвать и другие. Одного этого достаточно, чтобы доказать, что ваше утверждение неверно.
Я думаю, что ключевым моментом в пользу Фортрана является то, что это язык, немного более подходящий для выражения математики на основе векторов и массивов. Указанная выше проблема анализа указателя реальна на практике, поскольку переносимый код не может действительно предполагать, что вы можете что-то сообщить компилятору. Вычисления выражений ВСЕГДА имеют преимущество, близкое к тому, как выглядит домен. В C на самом деле вообще нет массивов, если вы присмотритесь, просто что-то подобное ведет себя. У Фортрана есть реальные массивы. Это упрощает компиляцию для определенных типов алгоритмов, особенно для параллельных машин.
Глубоко в таких вещах, как система времени выполнения и соглашения о вызовах, C и современный Фортран достаточно похожи, так что трудно понять, что может иметь значение. Обратите внимание, что C здесь действительно базовый C: C++ - это совершенно другая проблема с очень разными характеристиками производительности.
Когда я начал профессионально программировать, доминирование Фортрана в скорости было только вызовом. Помню, как читая об этом в Докторе Доббсе рассказывал про статью старшим программистам - они смеялись.
Так что у меня есть две точки зрения на этот счет: теоретическая и практическая. В теории Фортран сегодня не имеет существенных преимуществ перед C / C++ или даже любым языком, допускающим ассемблерный код. На практике Фортран сегодня по-прежнему пользуется преимуществами наследия истории и культуры, построенных на оптимизации числового кода.
Вплоть до Fortran 77 включительно при проектировании языка основное внимание уделялось оптимизации. Из-за состояния теории и технологии компиляторов это часто означало функции и возможности ограничение, чтобы дать компилятору наилучшие возможности для оптимизации кода. Хорошая аналогия - подумать о Fortran 77 как о профессиональном гоночном автомобиле, который жертвует характеристиками ради скорости. В наши дни компиляторы стали лучше на всех языках, и функции, повышающие продуктивность программистов, стали более ценными. Тем не менее, есть места, где люди в основном озабочены скоростью научных вычислений; эти люди, скорее всего, унаследовали код, обучение и культуру от людей, которые сами были программистами на Фортране.
Когда кто-то начинает говорить об оптимизации кода, возникает множество проблем, и лучший способ понять это - прятаться там, где есть люди, чья работа заключается в быстром числовом коде. Но имейте в виду, что такой критически чувствительный код обычно составляет небольшую часть общих строк кода и очень специализирован: большая часть кода на Фортране так же «неэффективна», как и многие другие коды на других языках и Оптимизация даже не должна быть основной задачей такого кода..
Замечательное место для начала изучения истории и культуры Фортрана - это Википедия. Запись Fortran в Википедии превосходен, и я очень ценю тех, кто потратил время и усилия, чтобы сделать его полезным для сообщества Fortran.
(Укороченная версия этого ответа была бы комментарием в отличной ветке, начатой Нильс, но у меня нет кармы, чтобы сделать это. На самом деле, я бы, вероятно, вообще ничего бы не написал, если бы в этой ветке не было фактических информационный контент и обмен информацией в отличие от пламенных войн и языкового фанатизма, что является моим основным опытом в этой теме. Я был потрясен, и мне пришлось разделить эту любовь.)
ссылка: web.archive.org/web/20090401205830/http://ubiety.uwaterloo.c a /… больше не работает. Есть альтернативная ссылка?
Есть еще один пункт, в котором Фортран отличается от C - и потенциально быстрее. В Фортране правила оптимизации лучше, чем в C. В Фортране порядок вычисления выражений не определен, что позволяет компилятору оптимизировать его - если кто-то хочет принудительно установить определенный порядок, нужно использовать круглые скобки. В C порядок намного строже, но с опциями «-fast» они более расслаблены, и «(...)» также игнорируются. Я думаю, что у Фортрана есть способ, который хорошо лежит посередине. (Что ж, IEEE усложняет жизнь, поскольку некоторые изменения порядка оценки требуют, чтобы не происходило переполнения, которое либо следует игнорировать, либо затрудняет оценку).
Еще одна область более разумных правил - комплексные числа. Мало того, что только до C 99 они были у C, еще и правила, управляющие ими, стали лучше в Фортране; поскольку библиотека Fortran gfortran частично написана на C, но реализует семантику Fortran, GCC получил возможность (которая также может использоваться с "обычными" программами на C):
-fcx-fortran-rules Complex multiplication and division follow Fortran rules. Range reduction is done as part of complex division, but there is no checking whether the result of a complex multiplication or division is "NaN + I*NaN", with an attempt to rescue the situation in that case.
Упомянутые выше правила псевдонимов - это еще один бонус, а также - по крайней мере в принципе - операции с целым массивом, которые, если их должным образом учитывать оптимизатором компилятора, могут привести к более быстрому выполнению кода. С другой стороны, некоторые операции занимают больше времени, например если кто-то выполняет присвоение размещаемому массиву, необходимо выполнить множество проверок (перераспределить? [функция Fortran 2003], есть шаги массива и т. д.), которые делают простую операцию более сложной за кулисами - и, следовательно, медленнее, но делает язык более мощным. С другой стороны, операции с массивами с гибкими границами и шагами упрощают написание кода - и компилятор обычно лучше оптимизирует код, чем пользователь.
В целом, я думаю, что и C, и Fortran примерно одинаково быстры; выбор должен заключаться в том, какой язык больше нравится, или более полезно использовать операции с целым массивом Fortran и его лучшая переносимость - или лучший интерфейс с системными библиотеками и библиотеками графического пользовательского интерфейса в C.
Что можно значимо «спасти» в случае Нан + ИНан? Что отличает бесконечности от NaN, так это то, что бесконечности подписаны. Операции с несложными бесконечностями, которые дадут запутанный знак, дают NaN, и я не вижу причин, по которым комплексные числа должны поступать иначе. Если один умножает (DBL_MAX, DBL_MAX) на (2,2), возводит результат в квадрат, а затем возводит в квадрат этот результат, каков должен быть знак результата при отсутствии переполнения? Какая единица умножает ее на (1.001, DBL_MAX)? Я считаю (NaN, NaN) правильным ответом, а любую комбинацию бесконечности и NaN бессмысленной.
Я сравниваю скорость 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, реализованные как указатели, могут быть оптимизированы по регистру.
Не бывает такого понятия, как один язык быстрее другого, поэтому правильный ответ - нет.
На самом деле вам нужно спросить, «скомпилирован ли код с помощью компилятора Fortran X быстрее, чем эквивалентный код, скомпилированный с помощью компилятора C Y?» Ответ на этот вопрос, конечно, зависит от того, какие два компилятора вы выберете.
Другой вопрос, который можно было бы задать, был бы примерно такой: «Учитывая то же количество усилий, затраченных на оптимизацию в их компиляторах, какой компилятор будет производить более быстрый код?» Фактически ответом на это будет Фортран. Компиляторы Fortran имеют определенные преимущества:
Однако ничто не мешает кому-то приложить массу усилий для оптимизации своего компилятора C и заставить его генерировать лучший код, чем компилятор Fortran их платформы. Фактически, более крупные продажи компиляторов C делают этот сценарий вполне осуществимым.
Я согласен. И позвольте мне добавить, что когда в конце 50-х - начале 60-х годов был представлен Фортран (это был первый язык высокого уровня), многие скептически относились к его эффективности. Поэтому его разработчикам пришлось доказать, что Фортран может быть эффективным и полезным, и приступить к «оптимизации его до смерти», просто чтобы доказать свою точку зрения. C пришел намного позже (с начала и до середины 70-х), и, так сказать, ему нечего было доказывать. Но к этому времени было написано много кода на Фортране, поэтому научное сообщество придерживалось его и до сих пор придерживается. Я не программирую на Фортране, но я научился ссылаться на подпрограммы Фортрана из C++.
Исследования по оптимизации компилятора были более разнообразными, чем вы думаете. История реализаций LISP, например, полна успехов в выполнении обработки чисел быстрее, чем Фортран (который по-прежнему остается претендентом на вызов по умолчанию). Кроме того, огромная часть оптимизации компилятора нацелена на промежуточные представления компилятора, что означает, что, не считая различий в семантике (например, псевдонимов), они применяются к любому языку программирования данного класса.
Идея повторяется много раз, но было бы немного лукавством сказать, что нет никаких последствий для эффективности, присущих дизайну языка программирования. Некоторые особенности языка программирования обязательно приводят к неэффективности, поскольку они ограничивают информацию, доступную во время компиляции.
@Praxeolitic - это совершенно правильно (поэтому мне приятно, что я не сказал ничего подобного).
@ТЕД. Честно говоря, вернувшись сюда через несколько месяцев, я понятия не имею, почему я оставил этот комментарий к вашему ответу. Может, я хотел оставить его где-нибудь еще? X-P
В некоторой степени Fortran был разработан с учетом оптимизации компилятора. Язык поддерживает операции с целым массивом, в которых компиляторы могут использовать параллелизм (особенно на многоядерных процессорах). Например,
Плотное матричное умножение просто:
matmul(a,b)
L2 норма вектора x равна:
sqrt(sum(x**2))
Кроме того, такие инструкции, как процедуры FORALL, PURE, ELEMENTAL и т. д., Дополнительно помогают оптимизировать код. Даже указатели в Fortran не так гибки, как C, по этой простой причине.
В грядущем стандарте Fortran (2008) есть сопряженные массивы, которые позволяют легко писать параллельный код. G95 (с открытым исходным кодом) и компиляторы от CRAY уже поддерживают его.
Так что да, Fortran может быть быстрым просто потому, что компиляторы могут оптимизировать / распараллеливать его лучше, чем C / C++. Но опять же, как и все в жизни, есть хорошие компиляторы и плохие компиляторы.
Вы также можете прочитать pimiddy.wordpress.com/2012/04/20/pure-functions-in-cc и open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0078r0.pdf.
Конструкция forall устарела, потому что компиляторы не могли хорошо оптимизировать код. Замена - do concurrent. Кроме того, код sqrt(sum(x**2)) выглядит неэффективным, поскольку компилятор, вероятно, строит весь вектор x**2. Я бы предположил, что цикл лучше, но, несомненно, лучше всего вызвать внутреннюю функцию norm2.
Большинство сообщений уже содержат убедительные аргументы, поэтому я просто добавлю пресловутые 2 цента к другому аспекту.
Быть fortran быстрее или медленнее с точки зрения вычислительной мощности, в конце концов, может иметь важное значение, но если для разработки чего-либо в Fortran требуется в 5 раз больше времени, потому что:
Тогда вопрос неактуален. Если что-то работает медленно, в большинстве случаев вы не можете улучшить это сверх заданного предела. Если вы хотите что-то побыстрее, измените алгоритм. В конце концов, компьютерное время стоит недорого. Человеческого времени нет. Цените выбор, который сокращает человеческое время. Если это увеличивает время работы компьютера, это в любом случае рентабельно.
проголосовали против, потому что, хотя вы поднимаете интересные моменты, которые добавляют к обсуждению преимуществ / недостатков fortrans по сравнению с другими языками (с чем я не полностью согласен), это на самом деле не ответ на вопрос ...
@steabert: на самом деле я сказал I will just add the proverbial 2 cents to a different aspect
+1 от меня за какой-то не придирчивый ответ. Как вы сказали, Фортран может быть быстрее в некоторых редких задачах (лично не видел). Но количество времени, которое вы тратите на поддержание неудобного языка, сводит на нет любое возможное преимущество.
-1. Похоже, вы думаете о Фортране с точки зрения F77. Это было заменено F90, F95, F03, и F08.
@KyleKanos: большинство пунктов все еще актуально с F9X / F2k3, кроме того, спецификации для 2k3 и 2k8, вероятно, невозможно полностью реализовать, и в любом случае я не хочу ждать до 2035 года. Я кодирую на C++ и python Теперь.
Проголосовали против, потому что в нем говорится исключительно об одной стороне компромисса. Скорость разработки может иметь значение для большинства общих программ, но это не единственный допустимый компромисс. Программисты Fortran часто являются учеными / инженерами, которые ценят простоту языка (FORmula TRANslation чрезвычайно легко изучить и освоить. C / C++ - это нет), отличные библиотеки (часто используемые из других языков) и скорость (например, моделирование погоды это занимает дни в Фортране, но месяцы, если они написаны полностью на других языках).
-1 «use iso_c_binding» нет ничего плохого в программировании на смешанных языках, как правильно демонстрирует ваш микс Python / C++.
@Kyle: вы были бы удивлены, насколько F77 все еще актуален в моей сфере.
Фортран поддерживает множество типов ввода-вывода. Я не понимаю вашего мнения о людях, не использующих функции, это их проблема, а не Фортрана. Он действительно поощряет модульность с «модулями» всего. Очень хорошая совместимость с C с использованием iso_c_binding, который является родным для Фортрана. Бесплатный компилятор Gfortran чертовски хорош. В нем никогда не будет всех функций, потому что постоянно добавляются новые.
Более быстрый код на самом деле не зависит от языка, это компилятор, поэтому вы можете увидеть «компилятор» 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
Пару лет я занимался математикой с помощью FORTRAN и C. По собственному опыту могу сказать, что FORTRAN иногда действительно лучше C, но не из-за его скорости (можно заставить C работать так же быстро, как FORTRAN, используя соответствующий стиль кодирования), а из-за очень хорошо оптимизированных библиотек, таких как LAPACK, и из-за отличное распараллеливание. На мой взгляд, с FORTRAN действительно неудобно работать, и его преимуществ недостаточно, чтобы устранить этот недостаток, поэтому теперь я использую C + GSL для вычислений.
Забавно, что здесь много ответов от незнания языков. Это особенно верно для программистов C / C++, которые открыли старый код FORTRAN 77 и обсуждают слабые места.
Я полагаю, что проблема скорости - это в основном вопрос между C / C++ и Fortran. В огромном коде это всегда зависит от программиста. Есть некоторые особенности языка, которые Фортран превосходит, и некоторые особенности, которые делает C. Итак, в 2011 году никто не может сказать, какая из них быстрее.
Что касается самого языка, Fortran в настоящее время поддерживает все функции ООП и полностью обратно совместим. Я тщательно использовал Fortran 2003, и я бы сказал, что пользоваться им было просто приятно. В некоторых аспектах Fortran 2003 все еще отстает от C++, но давайте посмотрим на его использование. Fortran в основном используется для численных вычислений, и никто не использует причудливые функции C++ ООП из-за соображений скорости. В высокопроизводительных вычислениях C++ почти некуда идти (взгляните на стандарт MPI, и вы увидите, что C++ устарел!).
В настоящее время вы можете просто программировать смешанные языки с помощью Fortran и C / C++. В Fortran есть даже интерфейсы для GTK +. Есть бесплатные компиляторы (gfortran, g95) и много отличных коммерческих.
Не могли бы вы добавить источник, конкретный опыт или научный институт / агентство высокопроизводительных вычислений, которое либо отходит от C++ для будущих проектов, либо переписывает проекты на C++ на другой язык. Я спрашиваю только потому, что знаю как минимум два научных учреждения, Sandia и CERN, которые активно используют C++ для своего высокопроизводительного моделирования. Кроме того, Sandia преобразовала одно из своих программ моделирования (LAMMPS) с fortran на C++, добавив ряд потрясающих улучшений.
LAMMPS написан на чрезвычайно простом C++, который не использует большинство современных возможностей языка. Он представляет собой C++, который программисты Fortran, знающие C, пишут после изучения C++ 98. Это не значит, что LAMMPS плохо написан, просто это не тот пример, который вы хотите приводить, защищая C++ в HPC.
У Fortran есть лучшие процедуры ввода-вывода, например подразумеваемая возможность do дает гибкость, которой не может соответствовать стандартная библиотека C.
Компилятор Fortran напрямую обрабатывает более сложные задействован синтаксис, и поэтому синтаксис не может быть легко сокращен в форму передачи аргументов, C не может реализовать это эффективно.
Есть ли у вас тесты, которые показывают, что Fortran превосходит C по вводу-выводу?
Фортран традиционно не устанавливает такие параметры, как -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.
Этот ответ действительно касается пользователей, которые не понимают флагов по умолчанию для своих компиляторов, а не самих языков.
Я программист-любитель, и я "средний" по обоим языкам. Мне легче писать быстрый код на Фортране, чем код на C (или C++). И Fortran, и C являются "историческими" языками (по сегодняшнему стандарту), широко используются и имеют хорошо поддерживаемые бесплатные и коммерческие компиляторы.
Я не знаю, исторический ли это факт, но Фортран кажется, что он построен для параллельной / распределенной / векторизации / любой-много-ядерной. И сегодня, когда мы говорим о скорости, это в значительной степени «стандартная метрика»: «масштабируется ли она?»
Я люблю Fortran за чистую обработку процессора. Для всего, что связано с вводом-выводом, мне легче работать с C. (в любом случае это сложно в обоих случаях).
Теперь, конечно, для параллельного математического кода вы, вероятно, захотите использовать свой графический процессор. И C, и Fortran имеют много более или менее хорошо интегрированного интерфейса CUDA / OpenCL (а теперь и OpenACC).
Мой умеренно объективный ответ: если вы знаете оба языка одинаково хорошо / плохо, то я думаю, что Fortran быстрее, потому что мне легче писать параллельный / распределенный код на Fortran, чем на C. (как только вы поняли, что вы можете писать fortran в произвольной форме и не просто строгий код F77)
Вот второй ответ для тех, кто хочет проголосовать против меня, потому что им не нравится первый ответ: оба языка имеют функции, необходимые для написания высокопроизводительного кода. Таким образом, это зависит от алгоритма, который вы реализуете (интенсивное использование ЦП? Интенсивное использование памяти?), Оборудования (один ЦП? Многоядерный? Распределенный суперкомпьютер? GPGPU? FPGA?), Ваших навыков и, в конечном итоге, самого компилятора. И C, и Fortran имеют отличный компилятор. (я серьезно поражен тем, насколько продвинуты компиляторы Fortran, но и компиляторы C - тоже).
PS: я рад, что вы специально исключили библиотеки, потому что я могу сказать много плохого о библиотеках графического интерфейса Fortran. :)
Быстро и просто: Оба одинаково быстры, но Фортран проще. Что действительно быстрее в конечном итоге зависит от алгоритма, но в любом случае существенной разницы в скорости нет. Это то, что я узнал на семинаре по Fortran в центре высокопроизводительных вычислений в Штутгарде, Германия, в 2015 году. Я работаю как с Fortran, так и с C, и разделяю это мнение.
Объяснение:
C был разработан для написания операционных систем. Следовательно, у него больше свободы, чем требуется для написания высокопроизводительного кода. В общем, это не проблема, но если не программировать внимательно, можно легко замедлить код.
Фортран был разработан для научного программирования. По этой причине он поддерживает синтаксис быстрого написания кода, так как это основная цель Fortran. В отличие от общественного мнения, Фортран не является устаревшим языком программирования. Его последний стандарт - 2010, и новые компиляторы публикуются на регулярной основе, поскольку большая часть высокопроизводительного кода написана на Фортране. Fortran также поддерживает современные функции в виде директив компилятора (в прагмах C).
Пример:Мы хотим предоставить большую структуру в качестве входного аргумента функции (fortran: подпрограмма). Внутри функции аргумент не изменяется.
C поддерживает как вызов по ссылке, так и вызов по значению, что является удобной функцией. В нашем случае программист может случайно использовать вызов по значению. Это значительно замедляет работу, поскольку сначала необходимо скопировать структуру в память.
Fortran работает только с вызовом по ссылке, что заставляет программиста копировать структуру вручную, если он действительно хочет вызвать операцию по значению. В нашем случае fortran будет автоматически работать так же быстро, как версия C с вызовом по ссылке.
Можете ли вы написать собственное параллельное приложение на C (то есть без вызова каких-либо библиотек?). Нет. Можете ли вы написать собственное параллельное приложение на Фортране? Да, несколькими способами. Следовательно, Фортран «быстрее». Хотя, честно говоря, в 2010 году, когда вы писали свой комментарий, поддержка параллельных функций do и co-array в Фортране, вероятно, не была так широко распространена, как сейчас.
@MaliRemorker Он написал это в 2016 году, а не в 2010 году.
Накладные расходы на создание параллельных процессов, на мой взгляд, не самый важный фактор для языка программирования, который называют «быстрым». Более уместны практические соображения, такие как неработающий кусок кода. Так что это ни к чему не поможет, если вы сэкономите время один раз (при создании параллельного процесса), а потом потратите его на несколько ядер. Термин «быстрый» также должен учитывать непараллельные коды. По этой причине я не вижу аргументов против своей точки зрения. Может быть, ваш комментарий воспринимался как самостоятельный ответ?
Используя современные стандарты и компилятор, нет!
Некоторые из присутствующих здесь предположили, что 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 имеют одинаковую производительность.
Было бы глупо верить чему-либо о Фортране из сообщения, которое предполагает, что это все еще Фортран. Все изменилось более 25 лет назад. Эти тесты не могут сравнивать языки, потому что они используют компиляторы от разных поставщиков, хотя и Intel, и GCC имеют компиляторы как для C, так и для Fortran. Следовательно, эти сравнения бесполезны.
Fortran может очень удобно обрабатывать массивы, особенно многомерные массивы. Нарезка элементов многомерного массива в Фортране может быть намного проще, чем в C / C++. В C++ теперь есть библиотеки, которые могут выполнять эту работу, такие как Boost или Eigen, но они, в конце концов, являются внешними библиотеками. В Фортране эти функции являются внутренними.
Будет ли Fortran быстрее или удобнее для разработки, во многом зависит от работы, которую вам нужно завершить. Как человек, занимающийся научными вычислениями в области геофизики, я большую часть вычислений выполнял на Фортране (я имею в виду современный Фортран,> = F90).
А также то, будет ли Фортран быстрее, также зависит от: используемого вами компилятора (это имеет значение!), От того, применяете ли вы соответствующее распараллеливание к коду, и от того, как ваш код написан.
Не совсем субъективно из ответов, приведенных ниже. Правильный заголовок: «Существуют ли какие-либо фундаментальные архитектурные причины, по которым компилятор Fortran МОЖЕТ производить лучший оптимизированный код, чем компилятор C», но это просто придирка.