2015-07-01 2 views
12

जब मैं -funroll-all-loops विकल्प मिला तो optimization options for GCC पढ़ रहा था।जीसीसी एक लूप को अनलोल कैसे कर सकता है यदि इसकी पुनरावृत्ति संख्या संकलन समय पर अज्ञात है?

इसका वर्णन पढ़ता है:

उतारना सभी छोरों, भले ही दोहराव हैं उनकी संख्या अनिश्चित है जब पाश दर्ज किया गया है। यह आमतौर पर प्रोग्राम धीरे-धीरे चलाता है। '-funroll-सभी छोरों' का अर्थ है के रूप में ही विकल्प '-funroll-छोरों'

कैसे संकलक एक पाश उतारना कर सकते हैं अगर पुनरावृत्तियों की संख्या संकलन समय पर अज्ञात है? क्या संकलक को इस जानकारी को अनलोल करने की आवश्यकता नहीं है? यह कौन सी संबंधित सी कोड उत्पन्न करता है, और यह कौन सा संदर्भ उपयोगी हो सकता है यदि यह आम तौर पर प्रोग्राम धीरे-धीरे चलाता है?

+5

@ ओलाफ यह एक विशिष्ट प्रश्न नहीं है? ओपी स्पष्ट रूप से पूछ रहा है कि कैसे जीसीसी (एक विशिष्ट सी कंपाइलर) यह जानने में सक्षम है कि लूप को अनलॉक करने के तरीके को कैसे अनलॉक किया जाए। –

+4

@ ओलाफ यह कितना व्यापक है यदि मैं जानना चाहता हूं कि एक विशिष्ट कंपाइलर विकल्प क्या करता है? –

+1

@ paulsm4 मुझे ऐसा नहीं लगता है। यदि संकलक पहले से ही सीमाओं को जानता है, तो निर्णय वास्तव में इसे अनलॉक करने के लिए कितना आता है। यह सवाल यह नहीं पूछ रहा है। –

उत्तर

3

क्या यह संदर्भ उपयोगी हो सकता है यदि यह आम तौर पर प्रोग्राम धीरे-धीरे चलाता है?

वैसे वे मानते हैं कि क्या आप यह विकल्प चुनते हैं कि आप जानते हैं कि आप क्या कर रहे हैं, अगर आपको यह विकल्प नहीं उपयोग करना चाहिए।

क्या जीसीसी करने जा रहा है, अच्छी तरह से मैं इस नमूना कार्यक्रम का इस्तेमाल किया:

#include <stdio.h> 

void f(int j) 
{ 
    for(int k = 0; k < j; ++k) 
    { 
    printf("%d\n", k) ; 
    } 
} 

और godbolt साथ यह परीक्षण किया है और उसे छोड़ दिया पुनरावृत्तियों की संख्या (see it live) के आधार पर एक कूद तालिका उत्पन्न करता है:

cmpl $1, %ebp 
movl $1, %ebx 
je .L1 
testl %r12d, %r12d 
je .L27 
cmpl $1, %r12d 
je .L28 
cmpl $2, %r12d 
je .L29 
cmpl $3, %r12d 
je .L30 
cmpl $4, %r12d 
je .L31 
cmpl $5, %r12d 
je .L32 
cmpl $6, %r12d 
je .L33 
+0

बेशक, वहां 'printf' के साथ, लाभ मूल रूप से शून्य है ;-) –

0

आप यह नहीं मान सकते कि इसी प्रकार की सी कोड एक कंपाइलर के मध्यवर्ती प्रतिनिधित्व के लिए ऐसी चीज है। लेकिन इस मामले में, मैं अपेक्षा करता हूं कि निकटतम समकक्ष Duff's Device जैसा कुछ हो, जो एक अनुक्रम (आमतौर पर एक लूप में) है जिसे गणना की गई जगह पर दर्ज किया जा सकता है।

2

ऐसा लगता है कि कुछ कर सकते हैं:

while(n >= 8){ 
    foo(); foo(); foo(); foo(); foo(); foo(); foo(); foo(); 
    n -= 8; 
} 
while(n > 0){ 
    foo(); 
    n--; 
} 

बेशक, गूंथा हुआ आटा के डिवाइस दूसरा पाश लिखने के लिए होने की बचत होगी।

ऐसा क्यों करें? यह उपयोगकर्ता के लिए है। मूल पाश समग्र दीवार-घड़ी समय का कम है कि 5%, या लेता है, तो अगर n आम तौर पर छोटी है, तो foo() कुछ चक्रों, या की तुलना में अधिक खर्च करता है, यह शायद मुसीबत के लायक नहीं है।

2

यहाँ कुछ सी इसे कैसे करना दिखा कोड है:

int iterations = 100; 
int unrollValue = 8; 

while (iterations%unrollvalue) 
{ 
    // insert loop code here 
    iterations--; 
} 

while (iterations) 
{ 
    // insert unrollValue copies of loop code here 
    iterations-= unrollValue; 
} 

संकलक एक रिश्तेदार छलांग के साथ पहली पाश की जगह लेगा, लेकिन यह सी में प्रतिनिधित्व करने के लिए आसान नहीं है ध्यान दें कि 2 के एक शक्ति से unrolling संकलक (महंगी) विभाजन ऑपरेशन के बजाय एक मुखौटा का उपयोग करने की अनुमति देता है।

+0

धन्यवाद। मैंने ठीक कर दिया। –

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