Дата публикации: Dec 23, 2012 7:37:58 PM
Фортран ориентирован на вычисления и с этим связан ряд его особенностей. С одной стороны, он довольно сильно отдален от "железа", поскольку в том и смысл, чтобы думать о массивах и переменных, а не о выделении памяти и адресах; с другой, о "железе" приходится думать, если хочется производительности. Опять же, с одной стороны - если не надо, то и думать не надо, то есть большинство свойств должно задаваться по умолчанию и по возможности использоваться эффективно; с другой, если надо, то надо, чтобы было - то есть побольше свойств должно быть доступно при желании, и максимально использоваться компилятором. Это все вопросы оптимизации кода.
В Фортране эти вопросы решаются беcкомпромиссно. А именно, предусмотрено множество атрибутов, самых разных. Они задаются по умолчанию, поэтому их можно не учить наизусть. Но их можно задавать, подсказывая компилятору пути возможной эффективной оптимизации. Либо наоборот, запрещая делать некоторые эффективные оптимизации, потому что нельзя. Давайте обсудим это подробнее.
Фортран, как любой нормальный язык, поддерживает рекурсию - вызов процедурой самой себя, в том числе косвенно, то есть через другую процедуру. Однако рекурсия нужна не всегда; в Фортране процедура рекурсивна тогда, когда она объявлена как таковая - имеет атрибут RECURSIVE. По умолчанию не имеет. Информация о том, что процедура не рекурсивна, может существенно помочь компилятору.
Аналогично обстоит дело со стерильностью - стерильная процедура не может ничего менять вне своего тела, в том числе осуществлять вывод. Стерильная функция может иметь только входящие аргументы; процедура может иметь и исходящие (в том числе смешанные), но с явно заданным атрибутом INTENT. Стерильная процедура имеет атрибут PURE. Он позволяет осуществлять многие оптимизации, в том числе - с перемещением кода. Поэлементная процедура по умолчанию стерильна, но можно отменить стерильность атрибутом IMPURE.
Ряд атрибутов относится не к процедурам, а к данным. Например, CONTIGUOUS, описывающий сплошной массив. Элементы сплошного массива расположены в памяти последовательно - это гарантируется. Плюс - возможны оптимизации, минус - строка матрицы не сплошна, так как матрица хранится по столбцам. Целью указателя может быть только объект с атрибутом TARGET. Это позволяет перемещать данные в памяти при необходимости, не заботясь о модификации указателей.
Помимо техники атрибутов, есть и другие средства для оптимизации. Отметим конструкции WHERE и FORALL, которые могут автоматически параллелиться, а также параллельный цикл DO CONCURRENT, итерации которого заведомо независимы. Поэлементные операции над массивами также допускают оптимизацию и распараллеливание: X = A + B - C можно выполнить одним циклом, а не двумя, как в случае, если поэлеметная операция перегружена средствами ООП. То же относится к поэлементным процедурам (атрибут ELEMENTAL), которые определены для скаляров, но могут принимать вместо них массивы одинаковой конфигурации. Многие встроенные функции поэлементны (все, для которых это уместно). Например, LOG(G) вычисляет логарифм для каждого элемента G, возможно, параллельно.