next up previous contents
След.: Алфавит программы и программные Выше: f08_new_win Пред.: Содержание   Содержание


Введение

Язык программирования Фортран уникален: будучи одним из старейших языков программирования, он на протяжении всей своей истории применялся на практике и был (и остается) современным и эффективным. Под «современным фортраном» ныне понимают стандарт Fortran-90/95, существенно отличный (но обратно-совместимый) от стандарта FORTRAN-77 (до сих пор поддерживаемого). Введены все черты современного языка, развились средства структурного и модульного программирования. После публикации стандарта Fortran-95 вышли еще два стандарта: Fortran-2003 и Fortran-2008 (2010 год). Добавлена полная поддержка объектно-ориентированного программирования, взаимодействия с операционной системой, асинхронного ввода/вывода, Unicode. Основное нововведение новейшего стандарта -- технология комассивов, реализующая параллельность стандартными средствами языка (еще введен параллельный цикл, итерации которого заведомо независимы, много встроенных функций, в том числе математических, и ряд других новшеств и усовершенствований). Компилятор GNU пока допускает только один образ (экземпляр параллельной программы), что приемлемо только для отладки. Впрочем, нет сомнений, что в ближайших версиях полная поддержка стандарта будет реализована. Реализации Coarray Fortran (нестандартный диалект) существовали еще до разработки стандарта Fortran-2008, в который вошла эта технология. Компилятор фирмы Intel, бесплатный для некоммерческого использования, частично поддерживает Fortran-2008 (включая комассивы) и успешно функционирует на кластере КарНЦ РАН[10].

Основная идея технологии комассивов -- параллельная работа нескольких копий программы, именуемых образами (images). Каждый образ имеет возможность определить свой номер и число всех образов. Объявленные данные в каждом образе -- свои, другие образы не имеют к ним доступа. Однако данные (переменные и массивы), объявленные как комассивы, доступны для чтения и записи другим образам. Доступ осуществляется по индексам по аналогии с индексами массива -- отсюда и название. Имеются средства синхронизации. Таким образом, параллельность введена в язык и стандартизована. Особенности архитектуры, методы коммуникации, организация памяти и прочие технические подробности остаются исключительно в ведении компилятора, на работу которого можно влиять посредством ключей.

Современный Фортран имеет все средства современного языка программирования общего назначения. Притом он располагает возможностями, удобными или облегчающими реализацию вычислительных алгоритмов: встроенные и определяемые пользователем поэлементные процедуры (так, SIN(X) вычисляет синус числа X, если это скаляр, либо вычисляет синусы всех элементов массива X произвольной конфигурации), параллельные циклы, операции над массивами, секции массива, векторные индексы, произвольные целые числа в качестве границ массивов. Указатели также реализованы с точки зрения удобства программирования вычислений; так, адресная арифметика отсутствует, зато есть возможность связи указателя с данными, расположенными в памяти не последовательно (например, допустимо присваивание указателю вида P => A(1:10:2), после которого указатель P является синонимом указанной секции массива -- выборке элементов с нечетных позиций). Механизм размещаемых массивов, технически также основанный на указателях, полностью скрывает технические подробности от программиста: ему доступна возможность определить размеры массива в ходе выполнения программы. Автоматические массивы позволяют работать с аргументами процедур-массивами в теле процедуры, не зная на этапе разработки размер массива. Необязательные параметры процедур повышают гибкость и удобство их использования, равно как и возможность использования ключевых параметров, доступных по имени. Богатые средства работы с файлами также облегчают ввод и вывод больших массивов данных в текстовой и двоичной форме. Фортран имеет много средств для облегчения разработки больших проектов: это концепция модулей и ее расширение -- подмодули, позволяющая разделять разработку при сохранении связей между частями программы; это объектно-ориентированное программирование, скрывающее детали реализации в классах; это классическая независимая компиляция, позволяющая раздельно компилировать и позже собирать в одну программу различные файлы, содержащие наборы процедур; это средства взаимодействия с языком C, введенный в Стандарт. Степень взаимодействия с операционной системой и аппаратным уровнем выбрана также с ориентацией на расчеты: низкоуровневые средства чрезвычайно малочисленны, адресная арифметика отсутствует, но есть стандартные процедуры для вызова команд операционной системы, доступа к переменным окружения, параметрам командной строки и системным часам. Ограничения призваны повысить переносимость. Однако весьма мощны средства работы с внутренним представлением чисел и конвертацией данных из текстовой формы во внутреннее представление. Система встроенных типов также ориентирована на вычисления: имеется комплексный тип, с которым естественно работают математические функции, технология разновидности типа позволяет управлять (в допускаемых системой рамках) точностью, диапазоном и т.п. чисел.

Многие возможности, встроенные в язык Фортран (и более того -- введенные в стандарт), реализуются в других языках с помощью библиотек и, возможно, перегрузки операций. Однако имеется существенная разница между средством языка и библиотечным вызовом. Особенно заметна она для пользователей, для которых программирование не является основным видом деятельности -- а к ним относится большое число прикладных математиков, физиков, биологов и других специалистов. Кроме того, встроенные в язык средства допускают более эффективную оптимизацию. Например, выражение A + B*COS(C**2), где A, B и C -- массивы одинаковой конфигурации, может быть вычислено одним циклом и оптимизирующий компилятор имеет возможность сделать именно так, поскольку анализирует встроенные в язык конструкции. В то же время, если подобная конструкция реализована через библиотечные вызовы и перегрузку операций, она вынужденно будет реализована четырьмя циклами.

Следует отметить, что Фортран вообще разработан для облегчения оптимизации кода. Так, рекурсивные функции поддерживаются языком, но рекурсивную функцию или подпрограмму необходимо объявить как рекурсивную (с атрибутом RECURSIVE) -- в противном случае рекурсивной она быть не может. В частности, имя нерекурсивной функции является именем по умолчанию возвращаемого значения (для рекурсивной функции это имя задается обязательно). Излишне пояснять, насколько эта информация (о том, что функция заведомо не рекурсивна) помогает оптимизатору. Аналогично, указатель может быть связан только с данными, объявленными как возможные цели (TARGET). Есть возможность объявить параметры процедур как входящие или исходящие: первые не могут быть изменены в теле процедуры, а значения вторых не важны и (пере)определяются в теле процедуры. Процедуру можно объявить как «стерильную» (PURE), то есть без побочного эффекта. Это означает, что процедура не меняет ничего вне своего тела (кроме своих аргументов, если это подпрограмма), в частности, не осуществляет ввод/вывод.

Языки программирования делятся на классы по парадигме -- системе идей и понятий программирования. Парадигма присуща языку, причем, как правило, не одна. Широко известны парадигмы императивного, структурного, модульного, функционального, логического и объектно-ориентированного программирования. Фортран, исторически, императивный язык: программа состоит из последовательности инструкций. Обладает он и ярко выраженными средствами структурного программирования: имеются возможности для разработки внешних, внутренних и модульных процедур; можно обойтись без безусловных переходов, управляя программой исключительно операторами цикла и условия; точка выхода из процедуры (в современном Фортране) единственна и совпадает с точкой входа; и т.д. Идеологически близкая модульная парадигма также сильна: поддерживаются модули, способные содержать открытые, экспортируемые данные и процедуры, закрытые, то есть внутренние, а также защищенные данные, то есть доступные только для чтения (а модификация возможно посредством модульных процедур); возможен полный или частичный экспорт открытых и защищенных объектов, в том числе с переименованием; имеются подмодули, позволяющие использовать модульный подход при разработке модулей. Поддерживается функциональная парадигма -- через концепцию стерильных процедур, которым запрещено менять что-либо за пределами своего тела, а аргументы функций, кроме того, только входящие; таким образом, результаты вычислений могут передаются из функции (как возвращаемое значение) в функцию (как аргумент). Вообще же функциональная парадигма декларирует отсутствие состояния в программе, то есть даже переменных нет: все вычисления производятся в телах функций над результатами, возвращаемыми функциями (роль цикла играет рекурсия). Есть полная поддержка объектно-ориентированного программирования: производные типы могут содержать (инкапсулировать) процедуры, типы могут расширять уже созданные типы (наследование), тип объекта может определяться на этапе выполнения (полиморфизм), и тип может определять и переопределять операторы выражений, присваивания и ввода/вывода (перегрузка операций). Парадигма логического программирования в явной форме отсутствует. Весьма существенны возможности векторизации: работы с массивами как целым. Поэлементные процедуры и операторы, функции редукции и секции массивов позволяют записывать выражения для массивов без применения циклов, в том числе -- вложенных. Современные процессоры значительно эффективнее выполняют векторизованные выражения по сравнению с циклами.

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

К недостаткам языка следует отнести довольно бедные возможности по обработке текста (на фоне мощнейшей системы ввода/вывода); а также «тяжелое наследие» -- средства, которые были оправданы и даже необходимы ранее, но излишни и даже вредны ныне. Имеется список нерекомендуемых черт языка, а ряд ранее нерекомендованных черт удаляется из нового стандарта. Тем не менее, многие черты поддерживаются для совместимости. Это фиксированный формат с его незначащими пробелами (ошибочная замена запятой на точку в конструкции цикла DO I=1,11 приведет к присвоению числа $ 1.11$ переменной DOI), жесткими ограничениями на длину строки (в результате чего переменные получают малопонятные короткие имена) и произвольным символом продолжения в шестой позиции, независимая компиляция, при которой не контролируется тип и число передаваемых в процедуру параметров, безусловные переходы и альтернативные выходы из процедур, указание завершающего оператора конструкции меткой и т.п. Однако с этими недостатками сталкиваются те, кто работает с чужим кодом, а при разработке собственных программ устаревших средств следует избегать. Следует отметить еще философское противостояние широты возможностей с неправильным их использованием. Так, неявная типизация, при которой тип переменной определяется по первому символу ее имени в отсутствие явного указания типа, удобна при использовании соглашения об именах, близкого к обычной математической традиции, однако чревата ошибками: опечатка в имени не приводит к ошибке компиляции. Есть возможность запретить неявную типизацию, но тогда каждую вспомогательную переменную необходимо декларировать, что не всем нравится. Можно считать недостатком также и отсутствие зарезервированных слов -- следующая программа-шутка вполне работоспособна, хотя совершенно нечитаема:

PROGRAM PROGRAM!

END:DO DO=DO,DO

PRINT*,DO,':END DO'

END DO END;END!??

Задача настоящего пособия состоит в изложении конструкций (включая новейшие) современного Фортрана для специалиста-непрограммиста. Материалов по современному (в смысле последнего опубликованного стандарта Fortran-2008) на русском языке недостаточно; настоящее пособие призвано отчасти закрыть этот пробел. Не ставится задача осветить стандарт полностью; ряд устаревших и нерекомендуемых черт не описывается, объектно-ориентированное программирование и средства взаимодействия с языком C описаны обзорно. По стандарту Fortran-90/95 материалов достаточно [2], описание новшеств Fortran-2003 также доступны [3,12], как и основного нововведения Fortran-2008 -- комассивов (на английском языке)[13]. Предполагается, что читатель ориентируется в терминологии программирования и схеме работы компьютера, хотя ряд определений дается в тексте. В области русскоязычной терминологии Фортрана мы ориентируемся на книгу [2]. Немногочисленные формулы и математические понятия предполагаются известными читателю; во всяком случае, квалификация читателя должна позволить найти соответствующие определения самостоятельно.



Ilya A. Chernov 2012-12-19
X