考虑以下基于C ++ 11循环的范围
for ( T k : j )
{
...
}
有g++
或clang++
优化标志可以加快编译代码的速度吗?
我不是在谈论任何for
周期我只考虑这个新的C ++ 11结构。
答案 0 :(得分:3)
GCC documentation about auto-vectorization未提及有关基于范围的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. */
正如您所看到的,他们只做标准实际描述的内容。
答案 1 :(得分:3)
优化循环很少是为了优化实际的循环迭代代码(在这种情况下为for ( T k : j )
),而是非常关于优化循环中的内容。
现在,因为在这种情况下这是...
,所以不可能说,例如,展开循环是否有帮助,或者声明函数内联[或只是移动它们以便编译器可以看到它们并放置它们是内联的,使用自动矢量化,或者可能在循环中使用完全不同的算法。
上面段落中的示例更详细一点:
float
添加四个float
值。这比一次操作单个数据项更快(大多数时候,有时它没有任何好处,因为尝试组合不同的数据项然后整理计算完成时的内容会有额外的复杂性)。 但是...
过于模糊,无法说出上述哪些解决方案可以改善您的代码。