Опубликован: 18.12.2012 | Доступ: свободный | Студентов: 238 / 27 | Длительность: 03:25:00
Лекция 5:

Настройки, оптимизация*

Аннотация: Заключительная лекция посвящена вопросам повышения производительности с использованием компилятора Intel Visual Fortran. Рассматриваются директивы, опции компилятора и уровни оптимизации, директивы (* www.intuit.ru Оптимизация приложений с использованием компиляторов Intel.)

Презентацию к лекции Вы можете скачать здесь.

Роль компилятора

Получение кода максимально эффективного для используемого вычислительного комплекса.

Требования к программе

  • Легкая читаемость и модифицируемость
  • Легкая отладка
  • Быстрота исполнения

Разработчику необходимы

  • Надежная среда разработки
  • Разные уровни отладки и быстродействия
  • Возможность получать высокоэффективный код

Компилятор должен удовлетворить эти требования.

Настройки проекта

General – Общие (дополнительные папки, оптимизация, формат отладочной информации)
Optimization – Оптимизация (подробное описание)
Debugging – Отладка, включая инструменты для параллельных программ
Preprocessor – Настройка препроцессора (до компиляции)
Code Generation – Генерация кода с учетом архитектуры используемых процессоров
Language – Особенности Fortran 66, 77, 2003, настройка OpenMP, MPI, CoArray.
Compatibility – Совместимость с ранними версиями языка Fortran и его расширениями
Diagnostics – Уровни диагностики (уровни автопараллелизации, векторизации, проверка интерфейсов)
Data – Настройка типов данных
Floating Point – Контроль чисел с плавающей точкой
External Procedures – Работа с внешними процедурами
Output Files – Выходные файлы (листинг, ассемблерный код, объектные файлы)
Libraries – Библиотеки (portlib, mkl)
Command Line – Общий вид командной строки

Оптимизация проекта

Optimization

/Od – Отсутствие оптимизации (для режима отладки)
/O1 – Оптимизация размера исполняемой программы
/O2 – Максимальная скорость выполнения
/O3 – Задействует /O2 и, более агрессивные методы оптимизации (подстановка скаляров, раскрутка циклов, подстановка кода для исключения ветвлений).

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

Loop Unroll Count

Установка максимального числа раскруток циклов.

/Qunroll[:n] n - число раскруток, начиная с самого внутреннего цикла.
/Qunroll:0 - отключение раскрутки.
/Qunroll - выбор числа раскруток на усмотрение компилятора (значение по умолчанию).

Parallelization

Циклы – наиболее трудоемкие места в программе. Включение автопараллелизации для циклов.

Yes - /Qparallel
    

Threshold For Auto-Parallelization

/Qpar-threshold[[:]n]
    

Устанавливает порог для автопараллелизации циклов на основе вероятности повышения производительности. (Опция /Qparallel должна быть включенной)

n=0 - автопараллелизация независима от объёма вычислений
n=100 – циклы распараллелены если имеется 100% прирост производительности
n=1..99 – процентная вероятность повышения производительности при автопараллелизации

Threshold For Vectorization

/Qvec-threshold[[:]n]
    

Устанавливает порог для векторизации циклов на основе вероятности повышения производительности.

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

do while (delta < 1.0E-4)
  вычисления
end do
    
n=0 - всегда выполнять векторизацию
n=100 – циклы векторизованы если имеется 100% прирост производительности
n=1..99 – процентная вероятность повышения производительности при векторизации

Prefetch Insertion

/Qopt-prefetch[=n]
    

Оптимизация вставки упреждающей выборки. Уменьшение неудачных обращений в кэш. Требует опции "/O3" в разделе "Optimization" и "/QxSSSE3".

Minimum (/Qopt-prefetch = 1)
Medium (/Qopt-prefetch = 2)
Aggressive (/Qopt-prefetch = 3)
    

I/O Buffering

/assume:[no]buffered_io
    

Установка буферизованного ввода / вывода. Ускоряет работу с жестким диском. Актуально при вводе / выводе больших массивов данных.

Heap Arrays

/heap-arrays[[:]n]
    

Размещение временных массивов минимального размера n (в килобайтах) на "куче", а не на стеке.

Значение 0 - всегда выделять на "куче".
Значение 10 – массивы меньшие 10 килобайт размещать в стеке, большие или равно в "куче".
recursive subroutine f( n )
  integer :: n
  real :: x ( n )     ! размещение в "куче"
  real :: y ( 1000 )  ! размещение в стеке
    

Interprocedural Optimization

Single-file (/Qip)
Multi-file (/Qipo)
    

Межпроцедурная оптимизация по одному или нескольким файлам.

Enables MM Library Call

No (/Qopt-matmul-)
Yes (/Qopt-matmul)
    

Замена операции матричного умножения процедурами из библиотек поточной обработки.

Использование библиотеки обычно обеспечивают лучшую производительность.

Опция идет по умолчанию в /O3 вместе с /Qparallel

Директивы

Специальные инструкции включаемые в программу и управляющие компиляцией.

Директивы имеют высший приоритет по сравнению с опциями компилятора.

Воздействие только на часть кода программы.

Директивы начинаются со знака $, !MS$, !DEC$

Контроль исходного кода

Директивы $STRICT и $NOSTRICT.

$STRICT - использовать только стандарт
$NOSTRICT - позволяет использовать расширения Intel Fortran Compiler (по умолчанию)

Записываются в верхней части программной единицы: головной программе, внешней процедуре или модуле.

Формат исходного кода

Директивы $FREEFORM и $NOFREEFORM.

$FREEFORM – свободная форма кода
$NOFREEFORM – фиксированный формат

1 символ $ или !MS$ (директивы) *, С или ! - комментарии
1-5 метки операторов
6 символ продолжения (не ноль)
7-72 операторы
73 и выше игнорируются

Директива $FIXEDFORMLINESIZE установка длины строки фиксированного формата $FIXEDFORMLINESIZE:72 или 80 или 132

Условная компиляция

Директивы $DEFINE и $UNDEFINE.

$DEFINE – создание символической переменной
$UNDEFINE – удаление созданной переменной
!DEC$DEFINE symbol = value
    

Символическая переменная локальна, т.е. недоступна в программе. Используется вместе с директивами $IF и $IF DEFINED

Директивы $IF и $IF DEFINED.

$IF – условная компиляция
!DEC$IF (условие)
  операторы
!DEC$ELSEIF (условие)
  операторы
!DEC$ELSE
  операторы 
!DEC$ENDIF
    
$IF DEFINED(переменная) – проверка определения директивой $DEFINE
program prog

  !DEC$DEFINE PARAM = 2

  !DEC$IF (PARAM == 1)
    write(*,*) "Use numerical algorithm N 1 " 
  !DEC$ELSE
    write(*,*) "Use numerical algorithm N 2 " ! *****
  !DEC$ENDIF   

  !DEC$UNDEFINE PARAM

  !DEC$IF DEFINED(PARAM)
    write(*,*) "Use numerical algorithm....." ! *****
  !DEC$ELSE
    write(*,*) "No algorithm ................"
  !DEC$ENDIF

end
    

Управление отладкой

Директивы $DECLARE и $NODECLARE.

$DECLARE – предупреждения для необъявленных переменных (implicit none)
$NODECLARE – отмена предупреждений

Директива $MESSAGE вывод символьной строки во время компиляции

!DEC$MESSAGE: "Компиляция графической части"
    

для программ занимающих значительной время компиляции

Разновидности типа

Директивы $INTEGER и $REAL.

$INTEGER: 2, 4 или 8 – как объявлены переменные в операторе integer Распространяется на разновидности типа logical.
$REAL: 4, 8 или 16 – как объявлены переменные в операторе real Распространяется на разновидности типа complex.

Листинг исходного кода

Директива $TITLE вывод специального заголовка на каждой странице листинга кода программы.

Директива $SUBTITLE вывод специального подзаголовка на каждой странице листинга кода программы.

Работают при включенной опции Source Listing

Подключение библиотеки

Директива $OBJCOMMENT LIB: имя библиотеки помещает полное имя библиотеки с указанием пути в объектный файл.

program prog

!DEC$OBJCOMMENT LIB: "mkl_blas95.lib"
! или
! !DEC$OBJCOMMENT LIB: "D:\Intel\mkl\lib\ia32\mkl_blas95.lib"

  use mkl95_blas
  integer, parameter :: n = 5    ! количество элементов
  real :: a(n) = (/1,2,3,4,5/),& ! векторы
          b(n) = (/2,4,6,8,9/)  
  real res
  res = dot(a,b) ! скалярное произведение
  write(*,*) "Scalar product = ", res

end