दिलचस्प पोस्ट
पीडीएफ के लिए एचटीएमएल आईटीक्शशशिप? Html टेबल के लिए डेटालेट VueJs 2 के साथ वैश्विक डेटा संपूर्ण फ़ाइल को खोलने के बिना, ज़िप फ़ाइल से डेटा कैसे पढ़ा जाए <Ui: रचना> टेम्पलेटिंग का उपयोग करते समय, मुझे <f: मेटाडेटा> को कहाँ घोषित करना चाहिए? केवल सी # में दिनांक के लिए एक प्रकार – कोई दिनांक प्रकार क्यों नहीं है? Reactjs html में कनवर्ट करें किसी वेबसाइट पर फ़ोल्डर अपलोड करने का सबसे अच्छा तरीका क्या है? Encapsulation बनाम अमूर्त? एक MYSQL डीबी पर ब्लॉब के रूप में संग्रहीत एक छवि को पुनः प्राप्त करें Django उपयोगकर्ता प्रोफ़ाइल MySQL अल्पविराम से अलग किए गए मानों के साथ दो तालिकाओं में शामिल हों कैसे चेक करें कि jQuery.ajax () अनुरोध हैडर स्थिति "304 संशोधित नहीं है"? क्या गंज 2 टेम्पलेट इंजन के साथ कोणीय का उपयोग करना संभव है? एक निश्चित उपसमुच्चय आकार के साथ योग-सबसेट

एक व्यस्त प्रतीक्षा लूप को अनुकूलित करने से जीसीसी को कैसे रोकें?

मैं Atmel AVR microcontrollers के लिए एक सी कोड फर्मवेयर लिखना चाहता हूं। मैं इसे जीसीसी के जरिए संकलित करूँगा इसके अलावा, मैं कंपाइलर ऑप्टिमाइज़ेशन ( -Os या- -Os ) को सक्षम करना चाहता हूं, क्योंकि मुझे उन्हें सक्षम नहीं करने का कोई कारण नहीं है, और वे संभवतः विधानसभा मैन्युअल रूप से लिखने से बेहतर विधानसभा तरीके से उत्पन्न कर सकते हैं।

लेकिन मैं इच्छित कोड का एक छोटा टुकड़ा अनुकूलित नहीं करना चाहता। मैं कुछ समय से किसी फ़ंक्शन के निष्पादन में देरी करना चाहता हूं, और इस तरह मैं कुछ समय बर्बाद करने के लिए डू-नॉट लूप लिखना चाहता था। सटीक होने की कोई आवश्यकता नहीं है, बस कुछ समय प्रतीक्षा करें।

 /* How to NOT optimize this, while optimizing other code? */ unsigned char i, j; j = 0; while(--j) { i = 0; while(--i); } 

चूंकि एवीआर में मेमोरी एक्सेस बहुत धीमी है, इसलिए i और j को सीपीयू रजिस्टरों में रखा जाना चाहिए।


अद्यतन: मैं सिर्फ AVR Libc से util / delay.h और util / delay_basic.h पाया । यद्यपि अधिकांश समय यह उन कार्यों का उपयोग करने के लिए एक बेहतर विचार हो सकता है, लेकिन यह सवाल वैध और दिलचस्प बना हुआ है।

Solutions Collecting From Web of "एक व्यस्त प्रतीक्षा लूप को अनुकूलित करने से जीसीसी को कैसे रोकें?"

मैंने इस जवाब को डीएमकेबी के उत्तर से एक लिंक के बाद विकसित किया है, लेकिन इसका उत्तर उसके जवाब से अलग है।

जीसीसी के फ़ंक्शन के दस्तावेजों के दस्तावेजों का उल्लेख है:

noinline इस फ़ंक्शन विशेषता को एक फ़ंक्शन को इनलाइनिंग के लिए माना जाने से रोकता है। यदि फ़ंक्शन के पक्ष-प्रभाव नहीं हैं, तो इनलाइनिंग के अलावा अन्य ऑप्टिमाइजेशन हैं, जिससे फ़ंक्शन कॉल को अनुकूलित किया जा सकता है, हालांकि फ़ंक्शन कॉल लाइव है। ऐसी कॉल को दूर रखने के लिए, asm (""); डाल दिया जाए asm ("");

इससे मुझे एक दिलचस्प विचार मिला … आंतरिक लूप पर एक nop निर्देश जोड़ने के बजाय, मैंने वहां खाली विधानसभा कोड जोड़ने की कोशिश की, इस तरह से:

 unsigned char i, j; j = 0; while(--j) { i = 0; while(--i) asm(""); } 

और यह काम किया! उस लूप को अनुकूलित नहीं किया गया है, और कोई अतिरिक्त nop निर्देश नहीं डाला गया है।

और क्या है, अगर आप volatile उपयोग करते volatile , तो जीसीसी उन चर को राम में संग्रहित करेगा और अस्थायी रजिस्टरों को कॉपी करने के लिए ldd और std का एक गुच्छा जोड़ देगा। दूसरी तरफ यह दृष्टिकोण, volatile उपयोग नहीं करता है और इस तरह के ऊपरी भाग को उत्पन्न नहीं करता है।


अपडेट करें: यदि आप -ansi या -std का उपयोग कर कोड संकलित कर रहे हैं, तो आपको जीएससी दस्तावेज़ीकरण में वर्णित के रूप में __asm__ साथ asm कीवर्ड को बदलना होगा।

इसके अलावा, आप __asm__ __volatile__("") उपयोग भी कर सकते हैं यदि आपके विधानसभा का विधान हम उसे डालते हैं, यानी (यानी ऑप्टिमाइज़ेशन के रूप में एक लूप से बाहर नहीं ले जाना चाहिए)

घोषित करें i और j चर को volatile रूप में। यह इन चर को शामिल करने वाले कोड को अनुकूलित करने के लिए कंपाइलर को रोकेगा।

 unsigned volatile char i, j; 

अगर मेरे कंपाइलर के एवीआर संस्करण #pragma के पूर्ण सेट का समर्थन करता है तो मैं अपने सिर के ऊपर से नहीं जानती हूं (जीसीसी संस्करण 4.4 से सभी लिंक के दिलचस्प लोगों को), लेकिन यह वह जगह है जहां आप आमतौर पर शुरू करेंगे।

मुझे यकीन नहीं है कि अभी तक इसका उल्लेख क्यों नहीं किया गया है कि यह दृष्टिकोण पूरी तरह से गुमराह किया गया है और कम्पाइलर उन्नयन द्वारा आसानी से टूटी हुई है, आदि। यह उस समय के मान को निर्धारित करने के लिए अधिक मायने रखता है, जब तक आप प्रतीक्षा न करें और वर्तमान जब तक वांछित मूल्य पार नहीं हो जाता है X 86 पर आप इस उद्देश्य के लिए rdtsc उपयोग कर सकते हैं, लेकिन समय प्राप्त करने के लिए अधिक पोर्टेबल तरीके से clock_gettime (या आपके गैर- POSIX OS के लिए संस्करण) कॉल करना होगा। वर्तमान x86_64 लिनक्स clock_gettime लिए syscall से भी clock_gettime और आंतरिक रूप से clock_gettime का उपयोग rdtsc या, यदि आप एक syscall की लागत को संभाल सकते हैं, तो केवल clock_nanosleep के साथ शुरू करने के लिए clock_nanosleep का उपयोग करें …

उस पाश को एक अलग। सी फ़ाइल में रखें और एक फ़ाइल को अनुकूलित न करें। यहां तक ​​कि बेहतर कोडांतरक में उस दिनचर्या को लिखना और उसे सी से कॉल करना, अनुकूलक अभ्यस्त शामिल न हो।

मैं कभी-कभी अस्थिर बात करता हूं लेकिन आम तौर पर एक एएसएम फ़ंक्शन का निर्माण करता है जो बस उस फ़ंक्शन को कॉल करता है जो ऑप्टिमाइज़र के लिए / जबकि लूप तंग करता है, लेकिन इसे ऑप्टिमाइज़ नहीं कर सकता क्योंकि यह डमी फ़ंक्शन के लिए सभी कॉल करना है Denilson SA से nop जवाब एक ही बात करता है लेकिन यह भी कड़ी …

अस्थिर राख डालना चाहिए आप इस पर यहां अधिक पढ़ सकते हैं: –

http://www.nongnu.org/avr-libc/user-manual/optimization.html

यदि आप विंडोज पर काम कर रहे हैं, तो आप नीचे दिए गए विवरण के अनुसार, प्रगामा के तहत कोड डालकर भी कोशिश कर सकते हैं: –

https://www.securecoding.cert.org/confluence/display/cplusplus/MSC06-CPP.+Be+aware+of+compiler+optimization+when+dealing+with+sensitive+data

उम्मीद है की यह मदद करेगा।

मेरे लिए, जीसीसी 4.7.0 पर, रिक्त एएसएम को वैसे भी अनुकूलित किया गया था- ओ 3 (ओ-ओ 2 के साथ प्रयास न करें)। और रजिस्टर या वाष्पशील में एक आई ++ का उपयोग करके एक बड़ा प्रदर्शन जुर्माना (मेरे मामले में)

मैं क्या किया था एक और खाली समारोह के साथ लिंक है जो संकलक नहीं देख सकता है जब "मुख्य कार्यक्रम"

मूल रूप से यह:

घोषित इस समारोह के साथ "helper.c" बनाया गया (रिक्त फ़ंक्शन)

 void donotoptimize(){} 

फिर संकलित "जीसीसी helper.c -c -o helper.o" और फिर

 while (...) { donotoptimize();} 

इसने मुझे सबसे अच्छे परिणाम दिए (और मेरे विश्वास से, कोई ऊपरी भाग नहीं, लेकिन परीक्षण नहीं कर सकता क्योंकि मेरा कार्यक्रम इसके बिना काम नहीं करेगा :))

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

आप रजिस्टर कीवर्ड का उपयोग भी कर सकते हैं। रजिस्टर के साथ घोषित चर को सीपीयू रजिस्टरों में संग्रहीत किया जाता है।

आपके मामले में:

 register unsigned char i, j; j = 0; while(--j) { i = 0; while(--i); }