2013-03-07 36 views
10

Có cách nào để nói với kêu vang để unroll một vòng lặp cụ thể?clang: Lực lượng vòng lặp unroll cho vòng lặp cụ thể


Googling cho câu trả lời cung cấp cho tôi các tùy chọn dòng lệnh sẽ ảnh hưởng đến toàn bộ và không phải một vòng lặp đơn lẻ.


Có câu hỏi tương tự cho GCC --- Tell gcc to specifically unroll a loop --- nhưng câu trả lời được cung cấp ở đó không hoạt động với tiếng kêu.

Lựa chọn 1 đề nghị đó:

#pragma GCC optimize ("unroll-loops") 

dường như bị bỏ qua trong im lặng. Thực tế,

#pragma GCC akjhdfkjahsdkjfhskdfhd 

cũng bị bỏ qua âm thầm.

Phương án 2:

__attribute__((optimize("unroll-loops"))) 

kết quả trong một cảnh báo:

warning: unknown attribute 'optimize' ignored [-Wattributes] 

Cập nhật

joshuanapoli cung cấp một giải pháp tốt đẹp như thế nào để lặp qua mẫu Lập trình meta và C + +11 mà không tạo vòng lặp. Cấu trúc sẽ được giải quyết tại thời gian biên dịch dẫn đến nội dung được lặp lại nhiều lần. Trong khi nó không chính xác là một câu trả lời cho câu hỏi, về cơ bản nó đạt được điều tương tự.

Đó là lý do tại sao tôi chấp nhận câu trả lời. Tuy nhiên, nếu bạn tình cờ biết cách sử dụng vòng lặp C chuẩn (for, while) và buộc phải hủy bỏ nó - hãy chia sẻ kiến ​​thức với chúng tôi!

+1

Thông thường, trình biên dịch có ý tưởng rất hay khi thích hợp để bỏ vòng lặp và khi đó không phải là ý tưởng hay.Trường hợp đặc biệt bạn đang cố gắng giải quyết là nơi nào không áp dụng? –

+0

Nó có thể không * force * unrolling, nhưng '__attribute__ ((hot))' có thể đáng để thử. –

+1

@MatsPetersson Tôi muốn đo lường rõ ràng lợi ích của việc bỏ vòng lặp. Unroll viết tay thực sự tăng tốc mã 3 lần, nhưng trình biên dịch không tìm ra nó. – CygnusX1

Trả lời

8

Đối với chương trình C++, bạn có thể hủy vòng lặp trong ngôn ngữ. Bạn sẽ không cần phải tìm ra các tùy chọn trình biên dịch cụ thể. Ví dụ,

#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; 
} 

Ví dụ với chức năng vòng lặp phức tạp

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) 

Sử dụng một đóng cửa thay vì một đối tượng chức năng rõ ràng

int main(int argc, char* argv[]) 
{ 
    int accumulator{3}; 
    repeat<4>([&](std::size_t) 
    { 
    accumulator += 2; 
    })(); 
    std::cout << accumulator << std::endl; 
} 
+0

Vâng, đây là cách làm mặc định của tôi. Nhưng kể từ khi tôi đã ở trong một khuôn mẫu với các tham số cần phải nhận được vào 'loop_function' nó được thực sự xấu xí ... đó là lý do tại sao tôi đang tìm kiếm một số giải pháp" mắt dễ chịu ":) – CygnusX1

+0

Nếu bạn có thể sử dụng C + +11, sau đó bạn có thể sử dụng chức năng constexpr để cắt giảm tiếng ồn cú pháp mẫu. – joshuanapoli

+0

Không nếu chỉ một số tham số là constexpr/template và một số tham số động thông thường ... hoặc? – CygnusX1

Các vấn đề liên quan