Кроме того, как компилятор определяет степень развертывания цикла, предполагая, что все операции в цикле полностью независимы от других итераций.
Для MSVC есть только подсказка о независимости вектора: http://msdn.microsoft.com/en-us/library/hh923901.aspx
#pragma loop( ivdep )
Для многих других компиляторов, таких как Intel/IBM, Есть несколько практических советов по оптимизации цикла:
#pragma unroll
#pragma loop count N
#pragma ivdep
Существует ветка с людьми из MSVC ++ о эвристическом развертывании: http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/d0b225c2-f5b0-4bb9-ac6a-4d4f61f7cb17/
VC пытается сбалансировать скорость выполнения и размер кода. Вы можете изменить баланс, используя флаги / O1 или / O2, но даже при оптимизации скорости VC также пытается сохранить размер кода.
По сути, развертывание увеличит размер кода, поэтому он может быть ограничен в режимах Os и O1 (таблица режимов)
PS: Pragma выглядит как директива препроцессора, но это не так. Это директива для компилятора, и она игнорируется препроцессором.
В случае Intel Compiler:
#pragma loop count N помогает компилятору использовать лучшую стратегию для векторизации цикла. Это экономит время. Таким образом, мы можем сказать, что это помогает развернуть цикл.
Примеры:
#pragma loop_count min(n),max(n),avg(n)
#pragma unroll (n) работает только при использовании с флагом -O3, вы можете использовать следующую стратегию, чтобы развернуть цикл в соответствии с целевым процессором.
Помимо увеличенного кода, генерируемого развертыванием цикла, это может стоить, так как компилятор будет создавать версию цикла для скалярных операций, а также для векторных операций.
В случаях, когда развертывание влияет на производительность, например: цикл с 20 итерациями с длиной вектора 16, приводит к 1 циклу, который выполняет 16 операций одновременно, и к циклу остатка, который выполняет 4 последовательно.
Чтобы избежать цикла остатка, сгенерированного компилятором, мы можем использовать перед циклом:
#pragma vector novecremainder //or -mP2OPT_hpo_vec_peel = F to disable peel and remainder loops (compiler internal option)
или же
#pragma nounroll //where unrolling is not worth at all
Просто чтобы уточнить #pragma ivdep :
Надеюсь это поможет.