2013-03-07 3 views
10

के लिए फोर्स लूप अनलोल करें क्या विशिष्ट लूप को अनलॉक करने के लिए क्लैंग को बताने का कोई तरीका है?क्लैंग: विशिष्ट लूप


उत्तर के लिए गुगलिंग मुझे कमांड लाइन विकल्प देता है जो पूरे संकलक को प्रभावित करेगा और एक लूप नहीं।


जीसीसी --- 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 एक अच्छा समाधान कैसे टेम्पलेट metaprogramming और सी के माध्यम से पुनरावृति करने के लिए प्रदान करता है + लूप बनाने के बिना +11। निर्माण संकलन समय पर हल किया जाएगा जिसके परिणामस्वरूप बार-बार रेखांकित शरीर होता है। हालांकि यह वास्तव में सवाल का जवाब नहीं है, यह अनिवार्य रूप से एक ही चीज़ प्राप्त करता है।

यही कारण है कि मैं जवाब स्वीकार कर रहा हूं। हालांकि, यदि आपको पता है कि मानक सी लूप (for, while) का उपयोग कैसे करें और इसे अनलोल करने के लिए मजबूर करें - कृपया ज्ञान हमारे साथ साझा करें!

+1

आमतौर पर, संकलक के पास एक बहुत अच्छा विचार है जब यह लूप को अनलॉक करने के लिए उपयुक्त होता है और जब यह एक अच्छा विचार नहीं है।वह विशेष मामला क्या है जिसे आप हल करने की कोशिश कर रहे हैं जहां यह लागू नहीं होता है? –

+0

यह * बल * अनलोलिंग नहीं हो सकता है, लेकिन '__attribute__ ((गर्म)) 'कोशिश करने लायक हो सकता है। –

+1

@ मैट्स पीटरसन मैं लूप अनोलिंग के लाभ को स्पष्ट रूप से मापना चाहता हूं। हाथ से लिखित अनलोल वास्तव में कोड को 3 बार गति देता है, लेकिन संकलक इसे समझ नहीं पाता है। – CygnusX1

उत्तर

8

एक सी ++ प्रोग्राम के लिए, आप भाषा के भीतर लूप अनलोल कर सकते हैं। आपको कंपाइलर-विशिष्ट विकल्पों को समझने की आवश्यकता नहीं होगी। उदाहरण के लिए,

#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

+0

यदि आप सी + +11, तो आप टेम्पलेट सिंटैक्स शोर पर कटौती करने के लिए constexpr फ़ंक्शंस का उपयोग कर सकते हैं। – joshuanapoli

+0

नहीं, अगर केवल कुछ पैरामीटर constexpr/टेम्पलेट हैं और कुछ नियमित गतिशील पैरामीटर हैं ... या? – CygnusX1

2

सकल रूप में उपयोग करते हुए यह हो सकता है, आप फॉर-लूप को अपनी फाइल में अलग कर सकते हैं, इसे अलग से संकलित कर सकते हैं (अपनी कमांड लाइन झंडे के साथ) ।

relevant, but currently unanswered clang-developers question

1

बजना हाल ही में प्राप्त की पाश (जैसे #pragma unroll के रूप में) pragmas unrolling जो पूर्ण/आंशिक unrolling निर्दिष्ट करने के लिए इस्तेमाल किया जा सकता। अधिक जानकारी के लिए http://clang.llvm.org/docs/AttributeReference.html#pragma-unroll-pragma-nounroll देखें।