有没有办法告诉clang展开特定循环?
谷歌搜索答案给了我命令行选项,这将影响整个compilant而不是一个循环。
GCC有一个类似的问题--- Tell gcc to specifically unroll a loop ---但是那里提供的答案与clang无关。
选项1建议:
#pragma GCC optimize ("unroll-loops")
似乎被默默地忽略了。事实上
#pragma GCC akjhdfkjahsdkjfhskdfhd
也会被默默忽略。
选项2:
__attribute__((optimize("unroll-loops")))
会发出警告:
warning: unknown attribute 'optimize' ignored [-Wattributes]
更新
joshuanapoli提供了一个很好的解决方案,如何在不创建循环的情况下通过模板元编程和C ++ 11进行迭代。该构造将在编译时解析,从而产生重复内联的主体。虽然这不是问题的答案,但它基本上可以达到同样的目的。
这就是我接受答案的原因。但是,如果您碰巧知道如何使用标准C循环(for
,while
)并强制展开它 - 请与我们分享知识!
答案 0 :(得分:8)
对于C ++程序,您可以在语言中展开循环。您不需要找出特定于编译器的选项。例如,
#include <cstddef>
#include <iostream>
template<std::size_t N, typename FunctionType, std::size_t I>
class repeat_t
{
public:
repeat_t(FunctionType function) : function_(function) {}
FunctionType operator()()
{
function_(I);
return repeat_t<N,FunctionType,I+1>(function_)();
}
private:
FunctionType function_;
};
template<std::size_t N, typename FunctionType>
class repeat_t<N,FunctionType,N>
{
public:
repeat_t(FunctionType function) : function_(function) {}
FunctionType operator()() { return function_; }
private:
FunctionType function_;
};
template<std::size_t N, typename FunctionType>
repeat_t<N,FunctionType,0> repeat(FunctionType function)
{
return repeat_t<N,FunctionType,0>(function);
}
void loop_function(std::size_t index)
{
std::cout << index << std::endl;
}
int main(int argc, char** argv)
{
repeat<10>(loop_function)();
return 0;
}
具有复杂循环功能的示例
template<typename T, T V1>
struct sum_t
{
sum_t(T v2) : v2_(v2) {}
void operator()(std::size_t) { v2_ += V1; }
T result() const { return v2_; }
private:
T v2_;
};
int main(int argc, char* argv[])
{
typedef sum_t<int,2> add_two;
std::cout << repeat<4>(add_two(3))().result() << std::endl;
return 0;
}
// output is 11 (3+2+2+2+2)
使用闭包而不是显式函数对象
int main(int argc, char* argv[])
{
int accumulator{3};
repeat<4>( [&](std::size_t)
{
accumulator += 2;
})();
std::cout << accumulator << std::endl;
}
答案 1 :(得分:3)
Clang最近获得了循环展开编译指示(例如#pragma unroll
),可用于指定完全/部分展开。有关详细信息,请参阅http://clang.llvm.org/docs/AttributeReference.html#pragma-unroll-pragma-nounroll。
答案 2 :(得分:2)
尽可能粗略,您可以将所述for循环隔离到它自己的文件中,单独编译它(使用自己的命令行标志)。
relevant, but currently unanswered clang-developers question