2012-04-09 14 views
5

कोड को देखते हुए:लूप unrolling और अनुकूलन

for (int i = 0; i < n; ++i) 
{ 
    A(i) ; 
    B(i) ; 
    C(i) ; 
} 

और अनुकूलन संस्करण:

for (int i = 0; i < (n - 2); i+=3) 
{ 
    A(i) 
    A(i+1) 
    A(i+2) 
    B(i) 
    B(i+1) 
    B(i+2) 
    C(i) 
    C(i+1) 
    C(i+2) 
} 

मुझे कुछ करने के लिए स्पष्ट नहीं है: जो बेहतर है? मैं कुछ भी नहीं देख सकता जो दूसरे संस्करण का उपयोग करके किसी भी तेजी से काम करता है। क्या मुझसे कोई चूक हो रही है ?

सभी मुझे लगता है कि प्रत्येक अनुदेश पिछले अनुदेश के आधार पर किया जाता है, जिसका अर्थ है कि मैं प्रतीक्षा करने के लिए है कि पिछले अनुदेश आदेश के बाद एक शुरू करने के लिए खत्म हो जाएगा की जरूरत है ...

धन्यवाद

+1

कौन सी भाषा? – Bytemain

+0

विकिपीडिया के पास इसके लायक होने के लिए लूप अनलोलिंग के पीछे विचार पर एक अच्छा लेख है: http://en.wikipedia.org/wiki/Loop_unwinding –

+0

सामान्यतः, ये समकक्ष नहीं हैं। ए होना चाहिए (i); बी (i); सी (i); एक (मैं 1 +); बी (i + 1); इत्यादि – gnasher729

उत्तर

9

किसी कारक के उच्च-स्तरीय दृश्य में, आप अनुकूलन को देखने वाले नहीं हैं। स्पीड एन्हांसमेंट आपके पास जो कुछ है उसके साथ कंपाइलर करता है।

पहले मामले में, यह है की तरह कुछ:

LOCATION_FLAG; 
DO_SOMETHING; 
DO_SOMETHING; 
DO_SOMETHING; 
TEST FOR LOOP COMPLETION;//Jumps to LOCATION_FLAG if false 

आप बाद के मामले में देख सकते हैं, परीक्षण और कूद की भूमि के ऊपर ही है:

LOCATION_FLAG; 
DO_SOMETHING; 
TEST FOR LOOP COMPLETION;//Jumps to LOCATION_FLAG if false 

दूसरे में ऐसा कुछ है प्रति 1 निर्देश 1। पहले में 1 प्रति 1 निर्देश है; तो यह बहुत अधिक होता है।

इसलिए, यदि आपके पास इनवेरिएंट हैं तो आप भरोसा कर सकते हैं (आपके उदाहरण का उपयोग करने के लिए मॉड 3 की एक सरणी) तो लूप को खोलने के लिए यह अधिक कुशल है क्योंकि अंतर्निहित असेंबली अधिक सीधे लिखी जाती है।

3

है खैर, क्या यह कोड "बेहतर" या "बदतर" है, A, B और C के कार्यान्वयन पर निर्भर करता है, n के मूल्य जो आप उम्मीद करते हैं, आप किस कंपाइलर का उपयोग कर रहे हैं और आप किस हार्डवेयर पर चल रहे हैं।

आमतौर पर लूप अनोलिंग का लाभ यह है कि लूप करने का ओवरहेड (यानी i बढ़ रहा है और इसे n से तुलना कर रहा है) कम हो गया है। इस मामले में, 3.

4

लूप अनोलिंग का उपयोग & शाखा निर्देशों की संख्या को कम करने के लिए किया जाता है जो संभावित रूप से लूप को तेजी से बना सकता है लेकिन बाइनरी के आकार को बढ़ाएगा। कार्यान्वयन और मंच के आधार पर, या तो तेज हो सकता है।

2

जब तक कार्य ए(), बी() और सी() समान डेटासेट को संशोधित नहीं करते हैं, तो दूसरा संस्करण अधिक समांतरता विकल्प प्रदान करता है।

पहले संस्करण में, तीन कार्य एक साथ चल सकते थे, कोई परस्पर निर्भरता नहीं मानते थे। दूसरे संस्करण में, सभी तीन कार्यों को एक ही समय में सभी तीन डेटासेट के साथ चलाया जा सकता है, मानते हुए कि आपके पास पर्याप्त निष्पादन इकाइयां होती हैं, ऐसा करने के लिए कोई परस्पर निर्भरता नहीं होती है।

0

आम तौर पर "आविष्कार" अनुकूलन करने का प्रयास करने का अच्छा विचार नहीं है, जब तक कि आपके पास कठोर सबूत न हों कि आपको वृद्धि मिलेगी, क्योंकि कई बार आप एक गिरावट शुरू कर सकते हैं। आमतौर पर इस तरह के सबूत प्राप्त करने का सबसे अच्छा तरीका एक अच्छा प्रोफाइलर के साथ है। मैं अंतर देखने के लिए प्रोफाइलर के साथ इस कोड के दोनों संस्करणों का परीक्षण करूंगा।

इसके अलावा, कई बार पाश नहीं है unrolling बहुत protable, जैसा कि पहले उल्लेख के रूप में, यह बहुत मंच, संकलक, आदि

इसके अतिरिक्त आपके संकलक विकल्पों के साथ खेल सकते हैं पर निर्भर करता है। एक दिलचस्प जीसीसी विकल्प "-floop-अनुकूलन", जिसे आप "-O, -O2, -O3, और -Os"

संपादित साथ ही साथ स्वचालित रूप से मिलता है, "-funroll-छोरों" देखो संकलक है विकल्प।

+0

इसके अलावा, इस बदले में देखो, फिर भी अद्भुत पाश अनलॉकिंग उदाहरण: [डफ का डिवाइस] (http://en.wikipedia.org/wiki/Duff%27s_device) – Brady

संबंधित मुद्दे