Циклы представляют собой структуры, трудно поддающиеся оптимизации. В зависимости от архитектуры процессора, компилятор может сократить количество итераций цикла, выполнив его "разворачивание" (Loop Unrolling). Такой прием дает два преимущества:
- приводит к уменьшению числа проверок условия окончания цикла и выполнения условных переходов по сравнению с числом "полезных" команд тела цикла;
- увеличивает размер блока инструкций, доступных для локальной оптимизации путем переупорядочения потока команд.
Разворачивание цикла – это способ оптимизации, при котором эффективность выполнения программы повышается за счет увеличения объема программного кода.
Количество повторений тела цикла называется фактором (коэффициентом) разворачивания цикла (unroll factor).
int x;
func (int n)
{
int j;
for (j=0; j<n; j++)
x += x;
}
После разворачивания цикл будет выглядеть так:
for (j=0; j<n; j+=4)
{
x += x;
x += x;
x += x;
x += x;
}
Большинство компиляторов выполняют разворачивание циклов с фактором 2 или 4 (4 всегда лучше!). В случае если количество итераций цикла n неизвестно на этапе компиляции, то необходима дополнительная проверка, гарантирующая выполнение точно заданного числа итераций. В конечном итоге разворачивание цикла должно быть выполнено компилятором с учетом как выигрыша от разворачивания цикла, так и проигрыша от вставки дополнительных проверок.