Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!
Я не знаю, на что будет похож язык 2000 года, но знаю, что он будет называться Фортран (Т. Хоар, 1982).
Первую часть статьи, рассказывающую об истории классического Фортрана (1953-1990), можно прочитать здесь.
Как отмечалось в первой части, условно эволюцию языка Фортран можно разделить на классический период (Фортран I – Фортран IV), когда ведущую роль в разработке занимала фирма IBM, язык абсолютно доминировал среди программистов (особенно в США) и сохранял значительную преемственность с самой первой версией; и современный период (Фортран 90 – Фортран 2018), когда разработка велась в основном ISO, синтаксис и семантика языка были значительно осовременены, но, несмотря на это, язык был уже вытеснен на периферию инструментальных средств. Версия Фортран 77 занимает промежуточное положение между этими периодами.
Фортран 90
С одной стороны, накапливалось несоответствие архаичных особенностей классического Фортрана существующим практикам программирования, а с другой – понемногу начали уходить на покой аксакалы, привыкшие к классическому Фортрану пятидесятых-шестидесятых годов, и приходить новые люди. В итоге 14-летних размышлений над судьбами программирования, ISO в 1991 году выпустил стандарт Фортран 90, радикальным образом поменявший синтаксис и семантику языка Фортран. Одно только согласование этого стандарта заняло 6 лет (первоначально он задумывался как Фортран 85).
В целом, сущность изменений сводилась к позиционированию современного Фортрана как языка параллельных и конвейерных вычислений. Стандарт вобрал в себя как многие свойства языка PL/I, так и дальнейшее развитие операций с массивами, которые впервые были реализованы в качестве расширений языка для векторно-конвейерных суперкомпьютеров, таких как Cray.
Фактически, современный Фортран (начиная с Фортрана 90) отличается от классического Фортрана настолько же, насколько современный C++ отличается от C, если не больше.
Основные нововведения Фортрана 90:
Формат написания кода стал свободным, упразднено деление строки на позиции. В конструкциях языка стало возможно использовать строчные буквы, и в честь этого даже название языка официально изменено с FORTRAN на Fortran. Комментарии стало возможно размещать в тех же строках, что и операторы.
Количество значащих символов в идентификаторах увеличено с 6 до 31.
Массивы теперь рассматриваются, как объекты первого класса. Арифметические операции и встроенные функции теперь могут принимать в качестве аргументов массивы. Возможно записывать литеральные константы и выражения, имеющие тип массива. Из массивов можно выделять сечения – подмассивы, которые также рассматриваются, как массивы, в том числе фильтруя элементы по логическим маскам. Введён оператор
WHERE
для селективного присваивания элементов массивов. Всё это – самое главное изменение; Фортран теперь стал позиционироваться, как язык работы с массивами, как ранее APL, и приобрёл богатый набор средств поддержки конвейерных вычислений.Появились единицы совместной компиляции – модули. Интерфейс модуля проверяется при компиляции использующего его кода.
Появились рекурсивные процедуры и функции, динамическое размещение переменных в памяти (в стеке и в куче), указатели.
Появилась спецификация входных и выходных формальных параметров.
Расширен синтаксис описания типов, позволяющий указывать множество атрибутов типа объекта.
Появились структурные типы данных и элементы объектно-ориентированного программирования.
Приняты расширения из военного стандарта, в том числе операторные скобки
DO
...END DO
, операторDO WHILE
, операторыCYCLE
иEXIT
, операторIMPLICIT NONE
. Стало считаться хорошим тоном автоматически начинать любой модуль сIMPLICIT NONE
.Появился оператор выбора
SELECT CASE
.Множество более мелких изменений.
Фортран 90 стал радикально более интересным языком, чем его предшественники, вобрал в себя многие современные достижения программирования, но при этом, в отличие от классического Фортрана, он начал становиться большим и сложным языком. Кроме того, новая концепция Фортрана окончательно ориентировала его на специализацию в области написания вычислительных программ, развивая вычислительные возможности языка и игнорируя другие ниши программирования.
Очень забавная история произошла в Фортране 90 с конструкторами массивов. В синтаксис языка необходимо было ввести специальные скобки для конструктора. Сейчас конструктор записывается, например, так: [ (x**i, i=0,N) ]
– массив, содержащий полином N-й степени от x. Здесь квадратными скобками обозначено массивное выражение, а круглыми – неявный цикл, представляющий собой+ генератор его элементов. Но нельзя ж было за какие-то 38 лет просто так взять и ввести в алфавит языка квадратные скобки, которые отсутствовали на перфораторе IBM 704 и даже на некоторых ранних устройствах S/360! Поэтому было принято компромиссное решение кодировать их диграфами (/
и /)
, то есть, в нашем случае, (/(x**i, i=0,N)/)
. Учитывая, что косые черты сами по себе могли иногда выступать в Фортране в качестве специфических скобок (например, в описании общего блока памяти), такая конструкция невероятно запутывала программистов, так как казалось, что тут три пары скобок, а не две.
К интересным особенностям современного Фортрана относится то, что он позволяет описывать массивы, количество измерений в которых заранее неизвестно.
Фортран 95
Дальше дело пошло проще. Всего через 6 лет, в 1997 году, был выпущен стандарт Фортран 95.
Введены дополнительные конструкции для векторных вычислений с массивами, такие как оператор
FORALL
и вложенныеWHERE
.Введён атрибут пользовательских функций
ELEMENTAL
, позволяющий им, подобно встроенным функциям, работать как со скалярными элементами, так и с массивами.Введены атрибуты
PURE
иIMPURE
, специфицирующие наличие побочного эффекта у функции.На 45 году разработки языка было решено ввести в алфавит квадратные скобки. Конструкторы приобрели человеческий вид.
Пример программы:
program poly
implicit none
integer, parameter :: n = 10
real :: A(0:n), X(0:n), x0, p
integer :: i
read *, (A(i), i=n,0,-1), x0
X = [ (x0**i, i=0,n) ]
p = dot_product (A, X)
print *, p
end program
Фортран 2003
Стандарт Фортран 2003 принят в 2004 году, в нём, наконец, был стандартизован асинхронный ввод-вывод. Набор атрибутов расширен для описания взаимодействия с программами на языке Си. Расширены средства динамического распределения памяти и поддержки ООП, которые всё равно в Фортране никто не использует.
В тот же период независимыми разработчиками был разработан и реализован интерфейс OpenMP для Фортрана и позже для C/C++, позволяющий управлять исполнением кода на параллельных и конвейерных архитектурах. Например:
!$omp parallel do
do i = 1, 100
a(i) = 2.*i
end do
Выполнение этого цикла будет автоматически разделено на части по числу процессорных ядер в системе, и эти части выполнятся параллельно (например, по 25 элементов на 4 ядрах).
Фортран 2008
Очень важный стандарт, принятый в 2010 году и до сих пор эффективно реализованный не во всех компиляторах, хотя и формально совместимых с ним.
Поддержка вычислительной модели Coarray Fortran для массивно-параллельных архитектур. Программа в Coarray Fortran параллельно запускается на массиве вычислительных узлов, и каждый экземпляр может работать либо со своими локальными переменными, либо с переменными другого узла. Так, если у нас есть переменная
integer :: i
, то простоi
будет означать значение на своём узле, аi[N]
– значение на узле N (а и правда, не вводить же в язык какие-нибудь фигурные скобки для межпроцессной коммуникации, после того, как всего 13 лет назад уже придумали квадратные для конструкторов массивов).Оператор параллельного цикла
DO CONCURRENT
. Например, заголовок циклаdo concurrent (i=1:100, j=1:200)
означает, что 20000 итераций могут независимо параллельно исполняться вычислительными ядрами в любых разбиениях. Теоретически это даёт то же самое, что и явное указание параллелизма в OpenMP, если компилятор поддерживает такое распараллеливание.Атрибут
ASYNCHRONOUS
для асинхронных переменных в MPP средах.Операторные скобки
BLOCK
...END BLOCK
, позволяющие локализовать переменные более узко, чем тело подпрограммы или функции (ещё одно заимствование из PL/I, имеющее, однако, дополнительную важность для гранулирования доступа к асинхронным объектам).Атрибут
CONTIGUOUS
для более эффективного управления памятью.
К этому моменту язык Фортран достиг уже внушающих уважение размеров. Описание языка IBM XL Fortran for AIX, которое автор полагает лучшим доступным изложением Фортрана 2008, занимает 1106 страниц мелким шрифтом.
Фортран 2018
Для разнообразия, стандарт Фортран 2018 действительно был принят в 2018 году. Он включает расширение возможностей по взаимодействию с языком Си и расширяет язык в части управления массивно-параллельными вычислениями.
Введён ряд операторов (
FORM TEAM
,CHANGE TEAM
,SYNC TEAM
,FAIL IMAGE
) и большое количество встроенных функций для объединения вычислительных узлов в “команды” для выполнения различных подзадач. Если в классической модели coarray образца 2008 года все узлы выполняют один и тот же код с разными данными, то в модели 2018 года узлы могут группироваться в команды для выполнения различных блоков кода разными командами.Введено понятие коллективности подпрограмм, которое по сути представляет собой реентерабельность внутри команды.
Пример программы:
! Вектор a длиной N*P распределён среди P узлов.
! Каждый узел для представления своей части
! вектора a использует массив A(0:N+1),
! содержащий относящиеся к узлу элементы и
! значения гало для обмена с соседями справа и
! слева. Узлы делятся на две команды, которые
! работают независимо, но периодически
! обмениваются гало. Перед обменом все узлы
! инициирующей обмен команды должны быть
! синхронизированы, и для обмена требуются
! коиндексы инициирующей команды.
USE, INTRINSIC :: ISO_FORTRAN_ENV, ONLY: TEAM_TYPE
TYPE(TEAM_TYPE) :: INITIAL, BLOCK
REAL :: A(0:N+1)[*]
INTEGER :: ME, P2
INITIAL = GET_TEAM()
ME = THIS_IMAGE()
P2 = NUM_IMAGES()/2
FORM TEAM(1+(ME-1)/P2,BLOCK)
CHANGE TEAM(BLOCK,B[*]=>A)
DO
! Вычисляем что-нибудь в команде
! ...
! Меняемся значениями гало с соседней командой
SYNC TEAM(INITIAL)
IF(ME==P2 ) B(N+1) = A(1)[INITIAL::ME+1]
IF(ME==P2+1) B(0) = A(N)[INITIAL::ME-1]
SYNC TEAM(INITIAL)
END DO
END TEAM
Из этой программы (скопированной непосредственно из документа ISO) видно, что современный Фортран получил практически все те особенности, за которые увлечённые программированием люди любили PL/I: он имеет огромное описание, многочисленные загадочные атрибуты объектов, позволяет использовать ключевые слова в качестве имён переменных и содержит много возможностей, специально предназначенных для таких случаев, которые обычный программист не встретит ни разу за всю свою жизнь.
Бонус: Будущий Фортран 2023
В 2023 году ожидается принятие нового стандарта, условно – Фортран 2023. Его основные ожидаемые нововведения:
Конструкция
NOTIFY
для синхронизации узлов через высокоскоростную сеть.Атрибут
SIMPLE
для подпрограмм и функций, которые не только не имеют побочных эффектов (PURE
), но и ссылаются на нелокальные переменные только через свои параметры. Это важно для оптимизации параллельных вычислений, так как такой код можно вызывать асинхронно в разных параллельных потоках.Спецификация коллективных подпрограмм расширена на случай, когда они выполняются с разным статусом ошибочного состояния на разных узлах.
Введён оператор
@
по сути для рефлексивного замыкания индексации массивов, когда вместо индексов массива выступает другой массив. Например,A(@[1,3])
– то же самое, чтоA(1,3)
. Естественно, можно написатьA(@V)
. Также можно описывать массивы, размерность которых задаётся другими массивами.Оператор
DO CONCURRENT
может включать спецификацию редукции, например:do concurrent (i = 1, n) reduce(+:a) reduce(max:b) a = a + x(i)**2 b = max(b,x(i)) end do
Здесь компилятор понимает, что, разбив этот цикл на параллельно выполняющиеся части, надо будет потом применить функцию редукции к частичным результатам. В существующих стандартах такой цикл нельзя было оформить в виде параллельного.
Синтаксический сахар: условные выражения, перечисления, больше полезных встроенных функций.
Ещё бонус: Как припасть к источнику благодати
Как понятно из вышеописанного, на сегодняшний день Фортран преимущественно является инструментом для программирования суперкомпьютеров с массивно-параллельной и, в меньшей степени, векторно-конвейерной моделью обработки. На таких машинах используются специализированные коммерческие компиляторы, такие как IBM XL Fortran, Cray Fortran и тому подобные. В то же время, есть что запустить и в домашних условиях.
Стандартом де-факто для обучения программированию на Фортране и некоммерческого использования является компилятор GNU Fortran (gfortran). Этот компилятор имеет общий кодогенератор с gcc, реализован на огромном количестве платформ (в том числе Linux, macOS, Windows). GNU Fortran полностью поддерживает стандарты Фортран 95, Фортран 90 и Фортран 77. Ещё он поддерживает значительную часть стандартов Фортран 2003 и Фортран 2008, а также кусочек стандарта Фортран 2018 (в части взаимодействия с Си). GNU Fortran компилирует циклы do concurrent, но, к большому сожалению, генерирует по ним последовательный код. Этот компилятор может распараллеливать код только при использовании конструкций OpenMP. В архитектуре x86_64 поддерживается конвейеризация в объёме векторных инструкций процессоров Intel и AMD.
Перспективным свободно распространяемым компилятором является flang, реализованный на базе llvm. Особенностью flang является кодогенератор, унаследованный от коммерческого компилятора фирмы NVIDIA, позволяющий автоматически компилировать код для использования конвейерных вычислений на графических акселераторах NVIDIA. Однако, flang пока не достиг стадии окончательно оформленного дистрибутива, предлагается только его сборка из актуальных исходных текстов, которая может представлять проблему в ряде окружений.
Разработка на Фортране поддерживается в свободно распространяемой IDE Eclipse. В штатном дистрибутиве поддерживается вариант настройки для научных вычислений, который включает поддержку компиляторов GNU Fortran, Intel Fortran, IBM Fortran XL. Доступна локальная и удалённая отладка. Использование Eclipse с Фортраном возможно в Linux, Windows и macOS (к сожалению, в последних версиях macOS сломана совместимость с отладчиком gdb, поддерживающим Фортран; с другой стороны, не станет же фортрановский программист расстраиваться из-за сломанного отладчика?)