2013-03-07 64 views
10

有没有办法告诉铛展开一个特定的循环?铛:强制循环展开具体循环


谷歌搜索答案给我的命令行选项将影响整个compilant,而不是一个单一的循环。


没有为GCC --- Tell gcc to specifically unroll a loop类似的问题---但答案只要不铛工作。

选项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)并强制展开它,请与我们分享这些知识!

+1

通常情况下,编译器有一个非常好的概念,何时适合展开循环以及何时不是个好主意。你试图解决哪些不适用的特殊情况? – 2013-03-07 15:53:39

+0

它可能不会*强制*展开,但'__attribute__((hot))'可能值得尝试。 – 2013-03-07 18:33:51

+1

@MatsPetersson我想明确衡量循环展开的好处。手写的展开实际上可以使代码加速3次,但编译器无法解决这个问题。 – CygnusX1 2013-03-07 21:39:30

回答

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; 
} 
+0

是的,这是我做这件事的默认方式。但是因为我已经在一个模板中有需要进入'loop_function'的参数,所以它变得非常难看......这就是为什么我要寻找更多“令人满意的”解决方案:) – CygnusX1 2013-03-07 21:36:20

+0

如果你可以使用C + +11,那么你可以使用constexpr函数来减少模板语法噪声。 – joshuanapoli 2013-03-08 02:24:35

+0

如果只有一些参数是constexpr /模板,并且有些参数是常规动态参数,或者不是? – CygnusX1 2013-03-08 06:55:10