Я работаю над программой для высокопроизводительных параллельных вычислений гидродинамики, которая требует много легкие циклы и, следовательно, получают примерно 30% производительности, если все важные циклы полностью развернуты.
Это можно легко сделать для фиксированного количества циклов с помощью директив компилятора: #pragma GCC unroll (16)
распознается обоими компиляторами, к которым я стремлюсь, компилятором Intel C++ ICC и GCC, в то время как #pragma unroll (16)
, к сожалению, игнорируется GCC. Я также могу использовать параметры шаблона или директивы препроцессора в качестве ограничений с ICC (аналогично тому, что вы можете сделать с nvcc), например
template <int N>
// ...
#pragma unroll (N)
for (int i = 0; i < N; ++i) {
// ...
}
or
#define N 16
#pragma unroll (N)
for (int i = 0; i < N; ++i) {
// ...
}
не выдавать ошибки или предупреждения с -Wall -w2 -w3
при компиляции с ICC, в то время как дополнительный синтаксис #pragma GCC unroll (N)
с GCC (-Wall -pedantic
) выдает ошибку в GCC 9.2.1 20191102 в Ubuntu 18.04:
error: ‘#pragma GCC unroll’ requires an assignment-expression that evaluates to a non-negative integral constant less than 65535
#pragma GCC unroll (N)
Кто-нибудь знает способ сделать развертку цикла на основе параметра шаблона с директивами компилятора переносимым способом (по крайней мере, работая с GCC и ICC)? На самом деле мне нужно только полное развертывание всего цикла, так что что-то вроде #pragma GCC unroll (all)
мне уже очень помогло бы.
Я знаю, что существуют более или менее сложные стратегии для развертывания циклов с шаблоном метапрограммирование, но, поскольку в моем приложении циклы могут быть вложенными и могут содержать более сложные тела циклов, я чувствую, что такая стратегия чрезмерно усложнит мой код и снизит читабельность.
#pragma GCC push_options
,#pragma GCC optimize ("unroll-loops")
,for ...
,#pragma GCC pop_options
, который, однако, не будет переносимым с ICC. - person dfrib   schedule 14.08.2020