учитывая следующий диапазон на основе цикла в C ++ 11
for ( T k : j )
{
...
}
имеются g++
или же clang++
флаги оптимизации, которые могут ускорить скомпилированный код?
Я не говорю о каких-либо for
цикл Я рассматриваю только эту новую конструкцию C ++ 11.
Оптимизация циклов очень редко связана с оптимизацией реального кода итерации цикла (for ( T k : j )
в этом случае), но очень много об оптимизации того, что в цикле.
Теперь, так как это ...
в этом случае невозможно сказать, поможет ли, например, развертывание цикла, или объявить функции как встроенные [или просто переместить их так, чтобы компилятор мог их видеть, и поместить их как встроенные], используя автоматическую векторизацию или, возможно, используя совершенно другой алгоритм внутри цикла.
Примеры в параграфе выше немного подробнее:
float
значения еще четыре float
в одной инструкции). Это быстрее, чем работать с одним элементом данных за раз (в большинстве случаев, иногда это бесполезно из-за дополнительных сложностей с попыткой объединить различные элементы данных, а затем с сортировкой, что происходит, когда вычисление закончено). Но ...
Слишком расплывчато, чтобы сказать, какое из перечисленных выше решений поможет улучшить ваш код.
НКУ документация об автовекторизации ничего не говорит о диапазоне на основе for
петля. Кроме того, его код сводится к:
{
auto && __range = range_expression ;
for (auto __begin = begin_expr,
__end = end_expr;
__begin != __end; ++__begin) {
range_declaration = *__begin;
loop_statement
}
}
Таким образом, технически говоря, любой флаг помогает автоматически векторизовать конструкции в этом виде регулярных for
должен автоматически векторизовать подобный диапазон на основе for
петля. Я действительно делаю это, компиляторы переводят только на основе диапазона for
петли к регулярному for
циклы, а затем пусть векторизация делает свою работу на этих старых циклах. Это означает, что нет необходимости в флаге, чтобы ваш компилятор автоматически векторизовал ваш диапазон for
Зацикливается на любом сценарии.
Так как реализация GCC была запрошена, вот соответствующий комментарий в исходном коде, описывающий, что на самом деле делается для основанного на диапазоне for
цикл (вы можете проверить файл реализации parser.c, если хотите взглянуть на код):
/* Converts a range-based for-statement into a normal
for-statement, as per the definition.
for (RANGE_DECL : RANGE_EXPR)
BLOCK
should be equivalent to:
{
auto &&__range = RANGE_EXPR;
for (auto __begin = BEGIN_EXPR, end = END_EXPR;
__begin != __end;
++__begin)
{
RANGE_DECL = *__begin;
BLOCK
}
}
If RANGE_EXPR is an array:
BEGIN_EXPR = __range
END_EXPR = __range + ARRAY_SIZE(__range)
Else if RANGE_EXPR has a member 'begin' or 'end':
BEGIN_EXPR = __range.begin()
END_EXPR = __range.end()
Else:
BEGIN_EXPR = begin(__range)
END_EXPR = end(__range);
If __range has a member 'begin' but not 'end', or vice versa, we must
still use the second alternative (it will surely fail, however).
When calling begin()/end() in the third alternative we must use
argument dependent lookup, but always considering 'std' as an associated
namespace. */
Как вы можете видеть, они не делают ничего, кроме того, что фактически описывает стандарт.