Обновить

Возвращение легенды: почему Fortran снова в топе и где его использовать сегодня

Уровень сложностиСредний
Время на прочтение10 мин
Охват и читатели8.3K
Всего голосов 24: ↑22 и ↓2+25
Комментарии18

Комментарии 18

Представьте, что вы — директор аэрокосмического агентства. У вас есть 5 миллионов строк Fortran-кода, который 40 лет считает аэродинамику крыла. Он проверен в десятках тысяч лётных часов, и в нём нет ни одной математической ошибки. Вам предлагают переписать это на Rust. За 3 года, командой из 50 человек, с бюджетом в 100 миллионов долларов. Вы согласитесь?

А чё, у нас на хабре много директоров аэрокосмических агенств захаживает?) Если смотреть с точки зрения исполнителя, то конечно лучше на Rust всё переписать за 5кк/месяц, чем "седеть" в пропёрженном НИИ и за 150к ковырять Fortran на поддержке.

лучше на Rust всё переписать

С точки зрения исполнителя это сказка. Три года ты пишешь новый код, тебя носят на руках за то, что ты «спас компанию от легаси». Но как только этот код встаёт в прод, и из-за ошибки округления в новой реализации (потому что Rust гарантирует безопасность памяти, но не гарантирует математическую корректность) у тебя падает модель прогноза погоды или лопается виртуальная турбина — всё, прощай 5кк. Виновным назначат именно того, кто сказал «давайте всё перепишем».

150к ковырять Fortran на поддержке

Сходить на сайты вакансий. Ключевое слово не просто Fortran, а Fortran HPC или Computational Scientist. Да, в региональном НИИ, который перебивается грантами, много не заплатят. Но если мы говорим о поддержке легаси в крупных конторах, там зарплаты совсем другого порядка. Просто эти вакансии не висят на HeadHunter с пометкой «удалёнка из Урюпинска». CUDA Fortran развивает целая NVIDIA.

Так что да, директора аэрокосмических агентств на Хабре, возможно, и не сидят. А вот их тимлиды и ведущие инженеры-расчетчики — очень даже заглядывают. И им, поверьте, плевать, на чём написан решатель, лишь бы он считал быстро и правильно. А Rust, при всём уважении, пока не даёт той предсказуемости IEEE-совместимой математики на векторизованных тензорах, которую даёт Fortran.

Сходить на сайты вакансий.

Тут еще надо учесть, что в подобных областях далеко не все вакансии закрываются через поиск на публичных сайтах. Это вообще последнее средство. Обычно начинают с поиска по личным связям. Грубо говоря, переманить хорошего спеца у конкурентов. Или перехватить, если он сам уходит.

Смешно. А что тогда в фортране 1e37 / 1e38 = 0?

https://fortran-lang.discourse.group/t/ifort-ifort-2021-8-0-1-0e-37-1-0e-38-0/4936?u=zaikunzhang

Ах да, ieee - это для педантов, а ФОРТРАН - ЭТО СКОРОСТЬ!!1 Если нужна правильная арифметика, так указывайте флагом компилятора, что нужно правильно, а не быстро.

Хороший пример, но практически с real*4 не работают.

А что тогда в фортране 1e37 / 1e38 = 0?

Проверил с ifx (2025.0.0), Win10 . Результат : 1e37/1e38 = 0.1000000, в том числе с /fp:fast. Те же результаты дает ifort (XE 2013, 14.0.2.176).

Видимо, ошибка компилятора, которая сейчас исправлена. Работать с single, да еще на границе представления данных?

Концепции владения — это больно.

Это не больно, это в худшем случае препятствует постижению через копипасту. Переписывать такое из одного текста в другой - ноцебо. У Rust есть фундаментальная проблема - кто способен хорошо понять Rust, тот и первый кандидат на измену с С++, но это не боль.

Если вы строите новый проект с нуля, где критически важна безопасность памяти, и у вас есть опытные системные программисты — берите Rust.

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

В остальном, мог бы поставить плюс - поставил бы, стало бы плюсов 6, а не 5 как сейчас. Я сам бы непременно начал с границ реальной области применимости - меня вообще бесит что из этого, для любой технологии, сделали Россию (a riddle, wrapped in a mystery, inside an enigma), вполне вероятно - с перечислнием всех модных фишек (есть - нет). И это было-бы, как видно по статье, ошибкой. У Fortran есть сильно вырвавшаяся вперёд козырная область, всем остальным действительно можно пренебречь.

Про Fortran могу добавить результат моего наивного теста на разделение живого и мёртвого, занятного и постылого - apt search <subj> в Termux. Fortran прошёл.

Спасибо за подробный комментарий.

Задача может быть из тех, где наличие единственного владельца не есть свойство предметной области.

В точку. Именно поэтому в научных кодах до сих пор царят глобальные массивы в общих блоках или модулях. Модель владения Rust там смотрится как слон в посудной лавке. А что такое «критически важная безопасность памяти»? В HPC это часто означает: «чтобы уборщица не споткнулась о провод и не вырубила ноду кластера», а не «чтобы хакер не прочитал куки». Тут да, вы правы, для числодробилок главное — детерминизм и отсутствие алиасинга, а не защита от переполнения буфера (хотя и она не лишняя).

Я сам бы непременно начал с границ реальной области применимости... И это было бы, как видно по статье, ошибкой. У Fortran есть сильно вырвавшаяся вперёд козырная область...

Да, структура статьи — это сознательная попытка пройти по грани между «хайпом возрождения» и «технической правдой». Если бы я начал с главы «Кому не нужен Fortran», статью бы просто не открыли, потому что 90% Хабра сразу прошли мимо. Моя задача была зацепить «шок-контентом» из заголовка, а уже в середине и особенно в таблице сравнения и заключении расставить точки над i. Соглашусь, что акцент стоило сместить ещё сильнее на «козырную область», возможно, в ущерб перечислению фишек. Учту в следующей статье, если буду писать про COBOL (шутка).

Про Fortran могу добавить результат моего наивного теста... apt search <subj> в Termux. Fortran прошёл.

Гениально). Если пакет есть в Termux на Android, то язык официально жив.

Это не больно, это в худшем случае препятствует постижению через копипасту... У Rust есть фундаментальная проблема — кто способен хорошо понять Rust, тот и первый кандидат на измену с С++

Согласен на 100%, формулировка про «боль» — это действительно упрощение. Но давайте поместим её в контекст аудитории. Это не системные программисты, пишущие ядро ОС. Это расчётчик-гидродинамик, который видит уравнение Навье-Стокса и хочет превратить его в код с минимальным когнитивным зазором. Для него борьба с Borrow Checker при реализации простого метода конечных разностей — это действительно лишнее трение. Ему не нужна измена ни с Rust, ни с C++. Ему нужно, чтобы A = B + C работало быстро и без сюрпризов с памятью. Поэтому в тексте я и оставил эту легкую провокацию — не чтобы принизить Rust, а чтобы подсветить разницу в пороге входа для конкретной профессии.

Ещё раз спасибо за комментарий. Ради такого стоит писать на Хабр, а не в закрытый чаты.

>работает? Не лезь!

Хорошо бы, этого принципа придерживались не только в научных расчётах.

А его и придерживаются. Там, где ошибка стоит дорого, любая правка тащит за собой огромный объем ретестов, а основная задача - чтобы работало, а не "выскочим первыми на рынок, баги будет править потом, когда юзеры багрепортов накидают".

Но вот на 10-й строчке восседает Delphi. А Fortran, язык, на котором писали ещё при царе Горохе и который, по мнению всей «модной» тусовки, давно должен лежать на свалке истории, стабильно держится в топ-15.

Да, а Scratch на 12 и растёт. Что как бы намекает на "экспертность" рейтинга.

Да, TIOBE — это такой себе барометр: если смотреть на него каждый день, можно решить, что главный язык человечества — это Scratch, а COBOL скоро обгонит JavaScript.

Но есть нюанс. Методология TIOBE построена на подсчёте поисковых запросов вида +"<language> programming". Scratch генерит тонны трафика от школьников и учителей, которые гуглят «как сделать игру про котика». Это завышает его позицию и обесценивает рейтинг как инструмент для выбора промышленного стека.

К сожалению, других публичных, глобальных и столь же медийных метрик популярности языков просто нет. PYPL (GitHub pulls) или RedMonk (Stack Overflow + GitHub) для Фортрана показывают ещё более грустную картину (потому что научные репозитории с 40-летним кодом лежат не на GitHub, а на закрытых серверах Министерства энергетики США).

Но если хочется более честной метрики «экспертности», давайте посмотрим на:

  1. Топ-500 суперкомпьютеров. По данным последних отчетов, Fortran используется в научных нагрузках более чем на 20% систем из списка (особенно в верхушке, где экзафлопсные машины вроде Frontier). Scratch, при всём уважении, там ноль.

  2. Бюджеты NSF и DOE. Если взять грантовые заявки по вычислительной физике, климату и астрономии, там требование «Experience with Fortran 90+ and MPI» стоит почти в каждой второй.

Да, код на FORTRAN, COBOL и иже с ними лежит точно не в гите, а на внутренних серверах компаний.

У нас вот свой Bitbucket (на наших серверах во внутреннем контуре) где десятки тысяч репозиториев и миллионы строк кода на RPG (намного больше, чем кода на С/С++).

Естественно, что ни на какой github все это никогда и ни при каких условиях не попадет.

код на FORTRAN

При этом он еще может отличаться полной нечитаемостью. Пример - MUMPS (mumps-solver.org ).

 001 C                   MOVE      *BLANKS       #OVSTR           40
 001 C                   Z-ADD     1             #OVIDX            2 0
 001 C     'USM2002'     CAT(P)    ZLINN         #OVSTR
 001 C                   MOVE      '142'         #OVSTR
 001 C     #OVSTR        LOOKUP    APW(#OVIDX)                            50
B002 C     *IN50         IFEQ      *ON
 002 C                   MOVEL(P)  APW(#OVIDX)   DSEPMS
 002 C                   EXSR      USA01R
E002 C                   ENDIF

Это старый RPG FIXED И вы мне будете рассказывать про нечитаемость :-)

"Потому что в слове чайник пропустили мягкий знак" (с)

Ну в целом таки да... Основная сложность в понимании тут заключается в тонкостях работы MOVE и его многочисленных модификациях - MOVE, MOVEL, MOVE(P), MOVEL(P), MOVEA...

Первая строка - заполнение переменной #OVSTR пробелами.

Далее - объявление #OVIDX типом с фиксированной точкой, 2 знака, 0 после запятой с одновременным занесением туда 1

Потом склейка строкового литерала 'USM2002' со значением переменной ZLINN и занесение результата в #OVSTR. А вот дальше магия...

MOVE '142' #OVSTR помещает строковый литерал '142' в конец #OVSTR (последние три позиции)

Дальше ищем строку #OVSTR в массиве строк APW. Поиск начинается с текущего значения #OVIDX (которое установлено в 1). Если строку нашли, то 50-й индикатор (*IN50) будет установлен в *ON (индикатор - логический тип принимающий значения *ON или *OFF, на самом деле тождественен CHAR(1) со значениями '1' или '0').

Если нашли и *IN50 = *ON, в #OVIDX будет содержаться индекс найденного элемента массива.

Ну а дальше MOVEL(P) которая уже нормально заносит найденный элемент массива (слева, (P) указывает на необходимость заполнить остаток результата пробелами) в переменную DSEPMS (если размер DSEPMS меньше чем APW(#OVIDX), ошибки не будет, просто обрежется то, что не влезло).

Современный RPGLE (free RPG) уже без всего этого. Там нормальный процедурный язык, без позиционности. И тот же lookup там выглядит абсолютно нормально

#OVRIDX = %LOOKUP(#OWRSTR: ARW);

Вернет индекс найденного элемента или 0 если не нашло.

Но вот аналогов MOVE сейчас нет. Есть обычное присвоение (слева, с обрезкой если не влезло или заполнением пробелами остатка), присвоение начиная справа или замена подстроки нужным значением. Т.е. вместо

MOVE '142' #OVSTR

Надо

%SUBSTR(#OVRSTR: %LEN(#OVRSTR) - 2) = '142';

Т.е. замена последних трех символов #OVRSTR значением '142'.

%substr, кстати, может использоваться как lvalue, так и rvalue - или заменить подстроку в строке или извлечь подстроку из строки.

А вот вместо

MOVEL(P) APW(#OVIDX) DSEPMS

будет просто

DSEPMS = APW(#OVIDX);

и вместо

'USM2002' CAT(P) ZLINN #OVSTR

тоже просто

#OVSTR = 'USM2002' + ZLINN;

Основная проблема fixed в его позиционности. Вложенные if или циклы читать невозможно - отступов нет. Поэтому первые 4 позиции - отведены под "метки". Скажем для внешнего if там ставят B001, для вложенного B002 и т.д. Соотвественно, для endif ставится E002, E001... Ну чтобы хоть как-то всю эту кашу развидеть можно было.

В общем, я со всем этим уже более 9-ти лет работаю, но fixed (хотя его немало попадается в старых модулях что на доработку приходят) все еще "по слогам" читаю, а свободно писать на нем так и не могу, только free... Благо компилятор понимает в том числе и мешанину из fixed и free кода - все новые вставки уже на free делаем

Fortran не умер. Он просто перестал быть языком для всех.

В НРС на нем написана половина кодов, в частности, используется для прогнозов погоды.

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

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации