2008-10-26 13 views
14

मैंने अतीत में एम्बेडेड सिस्टम के लिए परियोजनाओं पर काम किया है जहां हमने परिणामी निष्पादन योग्य के आकार को कम करने के लिए स्टैक वैरिएबल की घोषणा के आदेश को पुन: व्यवस्थित किया है। उदाहरण के लिए, अगर हम था:क्या सी संकलक स्टैक वैरिएबल को पुनर्व्यवस्थित कर सकता है?

void func() 
{ 
    char c; 
    int i; 
    short s; 
    ... 
} 

हम पुन: व्यवस्थित होगा इस होना करने के लिए:

void func() 
{ 
    int i; 
    short s; 
    char c; 
    ... 
} 
संरेखण के कारण

मुद्दों पहले एक परिणामस्वरूप ढेर अंतरिक्ष के 12 बाइट्स में इस्तेमाल किया जा रहा है और दूसरा एक में हुई केवल 8 बाइट्स।

क्या सी कंपेलरों के लिए यह मानक व्यवहार है या हम संकलक का केवल एक छोटा सा उपयोग कर रहे हैं?

ऐसा लगता है कि एक कंपाइलर छोटे निष्पादन योग्य आकार के पक्ष में स्टैक वैरिएबल को पुन: व्यवस्थित करने में सक्षम होना चाहिए यदि वह चाहता था। मुझे यह सुझाव दिया गया है कि सी मानक के कुछ पहलू इसे रोकते हैं, लेकिन मैं किसी भी तरह से सम्मानित स्रोत नहीं ढूंढ पाया।

बोनस प्रश्न के रूप में, क्या यह सी ++ कंपाइलर्स पर भी लागू होता है?

संपादित

जवाब है हां, C/C++ compilers ढेर चर पुनर्व्यवस्थित कर सकते हैं, तो आप एक संकलक निश्चित रूप से यह करता है कि का एक उदाहरण दे सकते हैं है? मैं संकलक दस्तावेज या कुछ ऐसा ही देखना चाहता हूं जो इसका बैक अप लेता है।

संपादित करें फिर

धन्यवाद आपकी मदद के लिए हर कोई। दस्तावेज़ीकरण के लिए, सबसे अच्छी बात मुझे लगता है कर लिया है कागज Optimal Stack Slot Assignment in GCC (पीडीएफ), नवीन शर्मा और संजीव कुमार गुप्ता, जो सवाल में 2003 में

परियोजना जीसीसी शिखर सम्मेलन की कार्यवाही में प्रस्तुत किया गया था यहाँ था के द्वारा होता है एआरएम विकास के लिए एडीएस कंपाइलर का उपयोग करना। उस कंपाइलर के लिए प्रलेखन में इसका उल्लेख किया गया है कि मैंने दिखाए गए घोषणाओं को ऑर्डर करने के लिए प्रदर्शन में सुधार कर सकते हैं, साथ ही स्टैक आकार, एआरएम-थंब आर्किटेक्चर स्थानीय स्टैक फ्रेम में पते की गणना कैसे करता है। उस कंपाइलर ने इसका लाभ उठाने के लिए स्थानीय लोगों को स्वचालित रूप से पुनर्व्यवस्थित नहीं किया था। यहां जुड़े पेपर का कहना है कि 2003 के जीसीसी ने एआरएम-थंब प्रोसेसर के संदर्भ के इलाके में सुधार के लिए स्टैक फ्रेम को पुनर्व्यवस्थित नहीं किया था, लेकिन इसका तात्पर्य है कि आप कर सकते हैं।

मुझे कुछ भी नहीं मिला जो निश्चित रूप से कहता है कि यह कभी भी जीसीसी में लागू किया गया था, लेकिन मुझे लगता है कि यह पेपर प्रमाण के रूप में गिना जाता है कि आप सभी सही हैं। एक बार फिर धन्यवाद।

उत्तर

22

चूंकि सी या सी ++ कंपाइलर्स के लिए प्रतिबंधित मानक में कुछ भी नहीं है, हाँ, संकलक ऐसा कर सकता है।

यह योग (यानी structs) के लिए अलग है, जहां सापेक्ष आदेश बनाए रखा जाना चाहिए, लेकिन फिर भी कंपाइलर बेहतर संरेखण प्राप्त करने के लिए पैड बाइट्स डाल सकता है।

आईआईआरसी नए एमएसवीसी कंपाइलर स्थानीय लोगों के बफर ओवरफ्लो के खिलाफ अपनी लड़ाई में स्वतंत्रता का उपयोग करते हैं।

एक साइड नोट के रूप में, सी ++ में, विनाश का आदेश घोषणापत्र के विपरीत क्रम होना चाहिए, भले ही संकलक स्मृति लेआउट को पीछे रखता हो।

(मैं अध्याय एवं छंद उद्धृत नहीं किया जा सकता है, हालांकि, इस स्मृति से है।)

0

यह कंपाइलर विनिर्देशक है, कोई भी अपना स्वयं का कंपाइलर बना सकता है जो अगर वह इस तरह से चाहता है तो उलटा होगा।

10

संकलक ढेर से चर को हटाने और यह केवल रजिस्टर बनाने के लिए भी नि: शुल्क है अगर विश्लेषण दर्शाता है कि का पता चर कभी नहीं लिया/प्रयोग किया जाता है।

+0

यह वास्तव में एक अच्छा बिंदु है। मैं इसके बारे में तब नहीं था जब मैं अपने सहकर्मी के साथ चर्चा कर रहा था। –

+1

यह एक ही रजिस्टर या स्टैक स्थान पर एकाधिक चर निर्दिष्ट भी कर सकता है यदि यह साबित कर सकता है कि चर के कोड के समान भाग में चर कभी जीवित नहीं होते हैं। यह सामान्य अभ्यास है, विशेष रूप से इनलाइन कोड के साथ जो कम परिवर्तनीय जीवन की ओर जाता है। –

4

एक कंपाइलर डेटा के लिए बिल्कुल एक स्टैक का उपयोग भी नहीं कर सकता है। यदि आप एक मंच पर इतने छोटे हैं कि आप ढेर के 8 बनाम 12 बाइट्स के बारे में चिंता कर रहे हैं, तो संभव है कि ऐसे कंपाइलर्स होंगे जिनके पास विशेष विशेष दृष्टिकोण हैं। (कुछ पीआईसी और 8051 कंपाइलर्स दिमाग में आते हैं)

आप किस प्रोसेसर के लिए संकलन कर रहे हैं?

+0

यह एक परियोजना के लिए था जिसे मैंने कुछ समय पहले काम किया था जहां हम कई एआरएम प्रोसेसर बनाने के लिए आर्म डेवलपर सूट (एडीएस) कंपाइलर के पुराने संस्करण का उपयोग कर रहे थे। मैं वास्तव में इस बारे में एक चर्चा सुलझाने के लिए कह रहा हूं कि अन्य कंपाइलर्स इसे कैसे संभालते हैं। –

0

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

जहां तक ​​मुझे पता है, ऐसा कुछ भी नहीं है जो कहता है कि किसी भी विशिष्ट स्थान या सी/सी ++ के ढेर पर संरेखण पर चर को रखने की आवश्यकता है; कंपाइलर उन्हें प्रदर्शन के लिए सबसे अच्छा और/या जो भी कंपाइलर लेखकों के लिए सुविधाजनक है, रखेगा।

+0

स्थानीय लोगों को लगभग किसी बिंदु पर ढेर में हमेशा डंप किया जाना चाहिए। इसका एकमात्र अपवाद यह है कि यदि आपका फ़ंक्शन * कभी भी * किसी अन्य फ़ंक्शन को कॉल नहीं करता है, तो इस मामले में सबकुछ क्षणिक होता है और बिना किसी स्टैक फ्रेम के संभाला जा सकता है। –

+0

... या यदि कोई चर फ़ंक्शन कॉल के आसपास नहीं रहता है। एक्स = एफ (एक्स) की तरह - पुराना मान एक रजिस्टर में हो सकता है, और नया मान फिर से रजिस्टर में जाता है। – gnasher729

10

ढेर की आवश्यकता भी मौजूद नहीं है (वास्तव में, सी 99 मानक में "स्टैक" शब्द का एक ही मौका नहीं है)। तो हां, संकलक तब तक ऐसा करने के लिए स्वतंत्र है जब तक वह स्वचालित भंडारण अवधि के साथ चर के अर्थशास्त्र को संरक्षित करता है।

उदाहरण के लिए: मुझे कई बार एक ऐसी स्थिति का सामना करना पड़ा जहां मैं डीबगर में स्थानीय चर प्रदर्शित नहीं कर सका क्योंकि यह एक रजिस्टर में संग्रहीत था।

0

AFAIK सी या सी ++ की परिभाषा में कुछ भी नहीं है जो निर्दिष्ट करता है कि कंपाइलर को स्टैक पर स्थानीय चर का ऑर्डर कैसे करना चाहिए। मैं कहूंगा कि इस मामले में संकलक क्या कर सकता है इस पर भरोसा करना एक बुरा विचार है, क्योंकि आपके कंपाइलर का अगला संस्करण इसे अलग-अलग कर सकता है। यदि आप अपने स्थानीय चरों को स्टैक के कुछ बाइट्स को बचाने के लिए समय और प्रयास करते हैं, तो उन कुछ बाइट्स आपके सिस्टम के कामकाज के लिए वास्तव में महत्वपूर्ण थे।

4

डीएसपी के टेक्सास उपकरणों 62xx श्रृंखला के लिए कंपाइलर सक्षम है, और "पूरे कार्यक्रम अनुकूलन" करता है। (आप इसे बंद कर सकते हैं)

यह वह जगह है जहां आपका कोड पुन: व्यवस्थित हो जाता है, न केवल स्थानीय। तो निष्पादन का आदेश समाप्त होता है जो आप उम्मीद कर सकते हैं।

C और C++ ऐसा नहीं वास्तव में एक स्मृति मॉडल वादा (के अर्थ में कहते हैं कि JVM), तो चीजें काफी अलग है और अभी भी कानूनी हो सकता है।

उन लोगों के लिए जो उन्हें नहीं जानते हैं, 62xx परिवार प्रति घड़ी चक्र डीएसपी के 8 निर्देश हैं; 750 मेगाहट्र्ज पर, वे 6e + 9 निर्देशों पर चोटी करते हैं। वैसे भी कुछ समय। वे समानांतर निष्पादन करते हैं, लेकिन निर्देशक आदेश कंपेलर में किया जाता है, सीपीयू नहीं, जैसे इंटेल x86।

पीआईसी और खरगोश एम्बेडेड बोर्ड स्टैक नहीं हैं जब तक कि आप विशेष रूप से अच्छी तरह से पूछें।

0

सी मानक की आवश्यकता के बारे में निष्क्रिय अटकलों की आवश्यकता नहीं है या इसकी आवश्यकता नहीं है: हाल ही के ड्राफ्ट ANSI/ISO working group से ऑनलाइन उपलब्ध हैं।

0

यह आपके प्रश्न का उत्तर नहीं देता है लेकिन यहां एक संबंधित मुद्दे के बारे में मेरा 2 सेंट है ...

मुझे स्टैक स्पेस ऑप्टिमाइज़ेशन की समस्या नहीं थी, लेकिन मुझे स्टैक पर डबल चर के गलत संरेखण की समस्या थी। किसी फ़ंक्शन को किसी अन्य फ़ंक्शन से बुलाया जा सकता है और स्टैक पॉइंटर मान में कोई भी गठबंधन मूल्य हो सकता है। तो मैं नीचे दिए गए विचार के साथ आया हूँ। यह मूल कोड नहीं है, मैं सिर्फ यह लिखा था ...

#pragma pack(push, 16) 

typedef struct _S_speedy_struct{ 

double fval[4]; 
int64 lval[4]; 
int32 ival[8]; 

}S_speedy_struct; 

#pragma pack(pop) 

int function(...) 
{ 
    int i, t, rv; 
    S_speedy_struct *ptr; 
    char buff[112]; // sizeof(struct) + alignment 

    // ugly , I know , but it works... 
    t = (int)buff; 
    t += 15; // alignment - 1 
    t &= -16; // alignment 
    ptr = (S_speedy_struct *)t; 

    // speedy code goes on... 
} 
38

इतना ही नहीं संकलक स्थानीय चर के ढेर लेआउट क्रम बदल सकते हैं, यह, रजिस्टर करने के लिए उन्हें आवंटित रजिस्टरों में कभी कभी जीने के लिए उन्हें प्रदान कर सकते हैं और कभी-कभी ढेर पर, यह स्मृति में एक ही स्लॉट में दो स्थानीय लोगों को असाइन कर सकता है (यदि उनकी लाइव श्रेणियां ओवरलैप नहीं होती हैं) और यह चर को पूरी तरह से खत्म भी कर सकती है।

+12

और उसे पता होना चाहिए – BCS

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