2012-03-20 6 views
5

मैंने किसी को एक बार सुना है कि कंपाइलर अक्सर लूप की स्थिति को लूप के नीचे ले जाते हैं। जो है, इस तरह के लूप:क्यों नीचे टेस्ट लूप बेहतर है?

if (condition) { 
    do { 
     ... 
    } while (condition); 
} 

मशीन स्वतंत्र अनुकूलन के बारे में, क्यों बाद बेहतर है:

while (condition) { 
    ... 
} 

करने के लिए बदल रहा है?

+0

वास्तव में, दूसरा पाश लूप के शीर्ष पर स्थिति का मूल्यांकन नहीं करता है। यह थोड़ी देर तक कूद जाता है, जहां यह जारी रहता है जैसे कि यह अभी एक पुनरावृत्ति समाप्त कर चुका है। शाखा भविष्यवाणीकर्ता का जिक्र करने के लिए –

उत्तर

7
संकलक अनुकूलन के बिना

, पहली पाश इस तरह विधानसभा कोड को जाता है:

@@: 
cmp ... ; or test ... 
jz @f 

... 
jmp @b 

जबकि दूसरा पाश कुछ इस तरह के लिए चला जाता:

jmp bottom 

    @@: 
... 

    bottom: 
cmp ... ; or test ... 
jz @b 

सशर्त छलांग आमतौर पर लिया जाना का पूर्वानुमान लगाया इसलिए पहली विधि संभावित रूप से अधिक पाइपलाइन/निर्देश कैश फ्लश का कारण बन सकती है।

हालांकि, सबसे महत्वपूर्ण बात यह है कि पहले लूप के लिए, प्रति लूप पुनरावृत्ति (2N) पर दो शाखाएं उपलब्ध हैं, जबकि दूसरी तरफ, प्रत्येक लूप पुनरावृत्ति में केवल एक शाखा है जो पहले बिना शर्त कूद के एक निश्चित ओवरहेड के साथ होती है (N+1)।

लूप अनुकूलन के बारे में अधिक जानकारी के लिए, इस assembly optimisation guide के पृष्ठ 88 देखें।

+2

+1, हालांकि, आप दूसरे उदाहरण में बिना शर्त कूद भूल गए। (दूसरा उदाहरण एक 'डू' लूप है, हम एक 'जबकि' लूप चाहते हैं।) आप कह रहे हैं कि दूसरा पाश कम जगह लेता है। –

+0

@ केंडलफ्रे: अच्छा पकड़, कोड अपडेट किया गया। –

+0

क्या दूसरी 'लूप संरचना' से निर्मित एक सीएफजी का कोई लाभ है जो इसे पहले लूप से बनाते समय मौजूद नहीं है? मेरा मतलब है, क्या यह अधिक अनुकूलन प्रवण है? – JohnTortugo

0

आप आंशिक रूप से गलत हैं।

jmp $test; 
$loop: 
    ; loop statements 
$test: 
    test <condition>; 
    branch-true $loop; 
इस से

बल्कि: ठेठ अनुकूलन यह है

$loop: 
    test <condition>; 
    branch-false $end; 
    ; loop statements 
    branch loop; 
$end: 

जो पाश के हर चरण में दो शाखाएं हैं। एक और फायदा यह है कि प्रारंभिक कूद के बाद भाग do/while के लिए उत्पन्न कोड के समान है।

0

असेंबली व्यू के लिए, एक लूप सिर्फ एक जंप निर्देश है जो कोड के पीछे कूदता है। तो कंपाइलर लूप के अंत में एक कूद डालने की जरूरत है।

कई निर्देश सेट, जैसे x86, एआरएम, एमआईपीएस सभी सशर्त कूद/शाखा निर्देश प्रदान करते हैं। चाहे कूद निर्देश में निर्दिष्ट शर्त पर निर्भर करे।

तो कंपेलर इस तरह के निर्देशों को प्राथमिकता देते हैं, और निर्देश का उपयोग करने के लिए लूप के अंत में स्थिति को स्थानांतरित करते हैं।