मैं कितना पुनरावृत्ति कर सकता हूं? मैं कितना पुनरावृत्ति कर सकता हूं? कितना सावधान! @ # QFSD @ $ RFW


19

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


2
क्या आप एक एल्गोरिथ्म का उदाहरण दे सकते हैं जहां पुनरावर्ती और गैर-पुनरावर्ती समाधान के बीच का विकल्प इतना स्पष्ट कटौती है?
Cybergibbons

1
@Cybergibbons सबसे हाल ही में, मुझे कुछ समय में RDP लिखना और परीक्षण करना पड़ा , इसलिए मैं पुनरावर्ती कार्यान्वयन के साथ आगे बढ़ा। मैं यह नहीं कह रहा हूं कि पुनरावृत्ति संभव नहीं है, बस यह कि पुनरावर्ती संस्करण के साथ आगे बढ़ना आसान हो सकता है।
अशेष

प्रश्न शीर्षक में इसका क्या अर्थ है How much ca!@#QFSD@$RFW:? मुझे इस बात की उत्सुकता है कि क्यों नहीं किसी ने संपादित किया है कि कुछ और सार्थक हो (पिछले 4 वर्षों में)।
निक गैमन

उत्तर कई 211बार (कई कारकों पर निर्भर करता है) :)। : मेरा उत्तर यहाँ देखें arduino.stackexchange.com/a/51098/7727 । @ निकमगॉन, वह "कोसने" का ढोंग करता है, मुझे लगता है। यह शब्द "पुनरावृत्ति" के लिए एक नाटक है। मुझे एक मिनट लगा कि यह भी पता लगाओ। पहले बहुत भ्रमित था।
गेब्रियल स्टेपल्स

ओह मैं समझा। मैंने सोचा था कि एसई सर्वर ख़राबी आ गई थी हो सकता है :)
निक गैमन

जवाबों:


15

यदि आप वास्तव में पुनर्विचार करना चाहते हैं (और जैसा कि @jippie ने कहा कि यह एक बुरा विचार है; अचेतन संदेश: यह मत करो ) और यह जानना चाहते हैं कि आप कितना पुनरावृत्ति कर सकते हैं, तो आपको कुछ गणना और प्रयोग करने होंगे; आपके पास भी आम तौर पर इसका केवल एक सन्निकटन होगा क्योंकि यह उस समय स्मृति स्थिति पर बहुत कुछ निर्भर करता है जब आपका पुनरावर्ती कार्य कहा जाएगा।

इसके लिए, आपको पहले पता होना चाहिए कि एवीआर-आधारित अरुडिनो के अंदर SRAM का आयोजन कैसे किया जाता है (यह इंटेल द्वारा Arduino गैलिलियो पर लागू नहीं होगा)। Adafruit का निम्न चित्र स्पष्ट रूप से दिखाता है:

SRAM संगठन

फिर आपको अपने SRAM का कुल आकार जानने की जरूरत है (Atmel MCU पर निर्भर करता है, इसलिए आपके पास किस तरह का Arduino बोर्ड है)।

इस आरेख पर, स्टैटिक डेटा ब्लॉक के ths आकार का पता लगाना आसान है क्योंकि यह संकलन-समय पर जाना जाता है और इसे नहीं बदलेगा।

ढेर आकार, के रूप में यह रनटाइम पर भिन्न हो सकते हैं और अधिक जानना मुश्किल हो सकता है गतिशील स्मृति आवंटन (पर निर्भर करता है mallocया new) अपने स्केच या पुस्तकालयों का उपयोग करता है के द्वारा प्रदर्शन किया। Arduino पर डायनामिक मेमोरी का उपयोग करना काफी दुर्लभ है, लेकिन कुछ मानक कार्य इसे करते हैं (प्रकार Stringइसका उपयोग करता है, मुझे लगता है)।

के लिए ढेर आकार, यह भी समारोह कॉल की वर्तमान गहराई के आधार पर रनटाइम के दौरान अलग अलग होंगे, (प्रत्येक समारोह कॉल ढेर पर 2 बाइट्स लेता है फोन करने वाले का पता स्टोर करने के लिए) और नंबर और पारित तर्क सहित स्थानीय चर का आकार ( अब तक कहे जाने वाले सभी कार्यों के लिए भी स्टैक पर ) संग्रहीत हैं।

तो मान लीजिए कि आपका recurse()फ़ंक्शन अपने स्थानीय चर और तर्कों के लिए 12 बाइट्स का उपयोग करता है, तो इस फ़ंक्शन के लिए प्रत्येक कॉल (बाहरी कॉलर से पहला और पुनरावर्ती वाले) 12+2बाइट्स का उपयोग करेगा ।

अगर हमें लगता है कि:

  • आप Arduino UNO (SRAM = 2K) पर हैं
  • आपका स्केच डायनेमिक मेमोरी एलोकेशन (कोई ढेर नहीं ) का उपयोग नहीं करता है
  • आप अपने स्टैटिक डेटा का आकार जानते हैं (आइए बताते हैं 132 बाइट्स)
  • जब आपका recurse()फ़ंक्शन आपके स्केच से कॉल किया जाता है, तो वर्तमान स्टैक 128 बाइट्स लंबा होता है

फिर आपको स्टैक2048 - 132 - 128 = 1788 पर उपलब्ध बाइट्स के साथ छोड़ दिया जाता है । आपके फ़ंक्शन में पुनरावर्ती कॉल की संख्या इस प्रकार है , जिसमें प्रारंभिक कॉल (जो पुनरावर्ती नहीं है) शामिल है।1788 / 14 = 127

जैसा कि आप देख सकते हैं, यह बहुत मुश्किल है, लेकिन यह असंभव नहीं है कि आप क्या चाहते हैं।

स्टैक के आकार को प्राप्त करने से पहले recurse()कहा जाने वाला एक सरल तरीका निम्नलिखित फ़ंक्शन का उपयोग करना होगा (Adafruit Learning Center पर पाया गया; मैंने इसे स्वयं परीक्षण नहीं किया है):

int freeRam () 
{
  extern int __heap_start, *__brkval; 
  int v; 
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); 
}

मैं आपको Adafruit Learning Center में इस लेख को पढ़ने के लिए प्रोत्साहित करता हूं ।


जब मैं मेरा लिख ​​रहा था तो मुझे उसका जवाब मिला। उसका उत्तर बेहतर दिखता है क्योंकि यह एक कॉल के बाद स्टैक की सामग्री का पूरी तरह से वर्णन करता है (मैं रजिस्टर राज्य भूल गया था)।
jfpoilpret

दोनों बहुत अच्छी गुणवत्ता के उत्तर।
साइबरबर्ग

स्टेटिक डेटा = .बीएस + + .डेटा, और क्या अर्डुइनो द्वारा "रैम को वैश्विक चर द्वारा लिया गया" या जो भी हो, सही बताया गया है?
गेब्रियल स्टेपल्स

1
@GabrielStaples हाँ बिल्कुल। अधिक विवरण .bssमें आपके कोड में कोई प्रारंभिक मूल्य नहीं के साथ वैश्विक चर का प्रतिनिधित्व करता है, जबकि dataएक प्रारंभिक मूल्य के साथ वैश्विक चर के लिए है। लेकिन अंत में वे एक ही स्थान का उपयोग करते हैं: आरेख में स्थैतिक डेटा
jfpoilpret

1
@ गैब्रिएलस्टैपल्स एक बात भूल गए, तकनीकी रूप से ये न केवल वैश्विक चर हैं, बल्कि आपके पास staticएक फ़ंक्शन के भीतर घोषित चर भी हैं ।
jfpoilpret

8

रिकर्सियन एक माइक्रोकंट्रोलर पर बुरा अभ्यास है जैसा कि आप पहले से ही अपने आप को बता चुके हैं और जब भी संभव हो आप इसे टालना चाहते हैं। Arduino साइट पर मुफ्त रैम आकार की जाँच के लिए कुछ उदाहरण और पुस्तकालय उपलब्ध हैं । उदाहरण के लिए आप इसका उपयोग यह जानने के लिए कर सकते हैं कि अपने स्केच और हार्ड कोड को प्रोफाइल करने के लिए रिकर्सन या बिट ट्रिकियर / रिस्कियर को तोड़ने के लिए इसका उपयोग करें। यह प्रोफ़ाइल आपके प्रोग्राम में हर बदलाव और Arduino टूल चेन में हर बदलाव के लिए आवश्यक होगी।


कुछ अधिक उच्च-अंत वाले संकलक, जैसे कि IAR (जो AVR का समर्थन करते हैं) और Keil (जो AVR का समर्थन नहीं करते हैं) आपके पास स्टैक स्थान की निगरानी और प्रबंधन करने में मदद करने के लिए उपकरण हैं। यह वास्तव में एक ATmega328 के रूप में छोटे रूप में कुछ पर उचित नहीं है।
साइबरबर्ग

7

यह फंक्शन पर निर्भर करता है।

हर बार किसी फ़ंक्शन को कॉल करने पर, एक नया फ़्रेम स्टैक पर धकेल दिया जाता है। इसमें आमतौर पर विभिन्न महत्वपूर्ण आइटम शामिल होंगे, जिनमें संभावित रूप से शामिल हैं:

  • वापसी का पता (उस कोड में बिंदु जहां से फ़ंक्शन कहा जाता था)।
  • thisयदि कोई सदस्य फ़ंक्शन कॉल कर रहा है, तो स्थानीय उदाहरण सूचक ( )।
  • पैरामीटर फ़ंक्शन में पास हुए।
  • मानों को पंजीकृत करें जिन्हें फ़ंक्शन समाप्त होने पर पुनर्स्थापित करने की आवश्यकता होती है।
  • स्थानीय चर के लिए स्पेस जिसे फंक्शन कहा जाता है।

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

जाहिर है स्टैक की स्थिति इस बात पर निर्भर करती है कि कोड में और क्या चल रहा है। यदि आप सीधे मानक loop()फ़ंक्शन के भीतर एक पुनरावृत्ति शुरू करते हैं, तो संभवतः पहले से ही स्टैक पर बहुत कुछ नहीं होगा। हालाँकि, यदि आप इसे शुरू करते हैं तो अन्य कार्यों में कई स्तर गहरा हो जाता है, तो इसमें ज्यादा जगह नहीं होगी। यह प्रभावित करेगा कि स्टैक को समाप्त किए बिना आप कितनी बार पुनरावृत्ति कर सकते हैं।

यह ध्यान देने योग्य है कि पूंछ पुनरावृत्ति अनुकूलन कुछ संकलक पर मौजूद है (हालांकि मुझे यकीन नहीं है कि अगर एवीआर-जीसीसी इसका समर्थन करता है)। यदि किसी फ़ंक्शन में पुनरावर्ती कॉल बहुत अंतिम चीज़ है, तो इसका मतलब है कि कभी-कभी स्टैक फ्रेम को बदलने से बचना संभव है। संकलक मौजूदा फ्रेम का फिर से उपयोग कर सकता है, क्योंकि 'पैरेंट' कॉल (बोलने के लिए) का उपयोग करके समाप्त हो गया है। इसका मतलब है कि आप सैद्धांतिक रूप से जितना चाहें उतना बार-बार दोहराते रह सकते हैं, जब तक कि आपका फ़ंक्शन कुछ और नहीं कहता है।


1
avr-gcc पूंछ पुनरावृत्ति का समर्थन नहीं करता है।
एशेशर

@AsheeshR - पता करने के लिए अच्छा है। धन्यवाद। मुझे लगा कि यह संभव नहीं था।
पीटर ब्लूमफील्ड

आप एक कोड कॉल एलिमिनेशन / ऑप्टिमाइजेशन कर सकते हैं अपने कंपाइलर से यह उम्मीद करने के बजाय कि यह क्या करेगा। जब तक पुनरावर्ती कॉल पुनरावर्ती विधि के अंत में है तब तक आप लूप के लिए थोड़ी देर / उपयोग करने की विधि को सुरक्षित रूप से फिर से लिख सकते हैं।
abasterfield

1
@ TheDoctor के द्वारा पोस्ट "avr-gcc पूंछ पुनरावृत्ति का समर्थन नहीं करता है", जैसा कि उनके कोड का मेरा परीक्षण करता है। संकलक ने वास्तव में पूंछ पुनरावृत्ति को लागू किया, जो कि वह एक लाख पुनरावृत्ति तक कैसे पहुंचा। पीटर सही है - कंपाइलर के लिए कॉल / रिटर्न (किसी फ़ंक्शन में अंतिम कॉल के रूप में) को बस जंप के साथ बदलना संभव है । इसका एक ही अंतिम परिणाम है और स्टैक स्पेस का उपभोग नहीं करता है।
निक गैमन

2

मेरे पास ठीक यही सवाल था क्योंकि मैं एलेक्स एलेन , च 16: रिकर्सियन, पी .230 द्वारा सी ++ में जंपिंग पढ़ रहा था , इसलिए मैंने कुछ परीक्षण किए।

TLDR;

मेरा Arduino नैनो (ATmega328 mcu) स्टैक ओवरफ्लो और क्रैश होने से पहले 211 पुनरावर्ती फ़ंक्शन कॉल (नीचे दिए गए कोड के लिए) कर सकता है।

सबसे पहले, मुझे इस दावे को संबोधित करने दें:

कभी-कभी, एक निश्चित एल्गोरिदम को लागू करने के लिए पुनरावृत्ति एकमात्र त्वरित विकल्प है।

[अपडेट: आह, मैंने "त्वरित" शब्द को स्किम किया। उस स्थिति में आपकी कुछ वैधता है। फिर भी, मुझे लगता है कि यह निम्नलिखित कहने लायक है।]

नहीं, मुझे नहीं लगता कि यह एक सही कथन है। मुझे पूरा यकीन है कि सभी एल्गोरिदम में बिना किसी अपवाद के एक पुनरावर्ती और गैर-पुनरावर्ती समाधान दोनों हैं। यह सिर्फ इतना है कि कभी-कभी यह काफी आसान हैपुनरावर्ती एल्गोरिथ्म का उपयोग करने के लिए। कहा जा रहा है कि, माइक्रोकंट्रोलर्स पर उपयोग के लिए पुनरावृत्ति बहुत अधिक है और संभवतः सुरक्षा-महत्वपूर्ण कोड में कभी भी अनुमति नहीं दी जाएगी। फिर भी, इसे माइक्रोकंट्रोलर पर करना संभव है। यह जानने के लिए कि आप किसी भी दिए गए पुनरावर्ती कार्य में कैसे "गहरे" जा सकते हैं, बस इसे परखें! इसे वास्तविक जीवन के परीक्षण के मामले में अपने वास्तविक जीवन के आवेदन में चलाएं, और अपनी आधार स्थिति को हटा दें ताकि यह असीम रूप से फिर से शुरू हो जाए। एक काउंटर का प्रिंट आउट लें और अपने लिए देखें कि आप "गहरे" कैसे जा सकते हैं ताकि आप जान सकें कि आपका पुनरावर्ती एल्गोरिदम आपके रैम की सीमाओं को जोर दे रहा है या नहीं, व्यावहारिक रूप से उपयोग किया जा सकता है। एक Arduino पर स्टैक ओवरफ्लो को मजबूर करने के लिए नीचे एक उदाहरण दिया गया है।

अब, कुछ नोट्स:

कितने पुनरावर्ती कॉल, या "स्टैक फ्रेम" आप प्राप्त कर सकते हैं, कई कारकों द्वारा निर्धारित किया जाता है, जिसमें शामिल हैं:

  • आपके RAM का आकार
  • आपके स्टैक पर कितना सामान पहले से मौजूद है या आपके ढेर में लिया गया है (यानी: आपकी मुफ्त रैम मायने रखती है free_RAM = total_RAM - stack_used - heap_used, या आप कह सकते हैं free_RAM = stack_size_allocated - stack_size_used)
  • प्रत्येक नए "स्टैक फ्रेम" का आकार जो प्रत्येक नए पुनरावर्ती फ़ंक्शन कॉल के लिए स्टैक पर रखा जाएगा। यह कहा जा रहा फ़ंक्शन और उसके चर और स्मृति आवश्यकताओं, आदि पर निर्भर करेगा।

मेरे परिणाम:

  • 20171106-2054hrs - तोशिबा सैटेलाइट w / 16 जीबी रैम; क्वाड-कोर, विंडोज 8.1: दुर्घटना से पहले मुद्रित अंतिम मूल्य: 43166
    • दुर्घटना के लिए कई सेकंड लगे - शायद 5 ~ 10?
  • 20180306-1913hrs डेल हाई-एंड लैपटॉप w / 64 जीबी रैम; 8-कोर, लिनक्स उबंटू 14.04 एलटीएस: दुर्घटना से पहले मुद्रित अंतिम मूल्य: 261752
    • वाक्यांश के बाद Segmentation fault (core dumped)
    • दुर्घटना के लिए केवल ~ 4 ~ 5 सेकंड या तो ले लिया
  • 20180306-1930hrs Arduino Nano: TBD --- ~ 250000 पर है और अभी भी गिनती कर रहा है --- Arduino ऑप्टिमाइज़ेशन सेटिंग्स के कारण इसे पुनरावृत्ति का अनुकूलन करना होगा ... ??? हाँ, यह मामला है।
    • #pragma GCC optimize ("-O0")फ़ाइल के शीर्ष पर जोड़ें और फिर से करें:
  • 20180307-0910hrs Arduino Nano: 32 kB फ़्लैश, 2 kB SRAM, 16 MHz प्रोसेसर: अंतिम मूल्य दुर्घटना से पहले मुद्रित: 211 Here are the final print results: 209 210 211 ⸮ 9⸮ 3⸮
    • 115 सेकंड के सीरियल बॉड-रेट पर छपाई शुरू होने के बाद केवल एक सेकंड का कुछ ही हिस्सा लिया - शायद 1/10 सेकंड में
    • 2 kiB = 2048 बाइट्स / 211 स्टैक फ्रेम = 9.7 बाइट्स / फ्रेम (यह मानते हुए कि आपके RAM का सभी स्टैक द्वारा उपयोग किया जा रहा है - जो वास्तव में ऐसा नहीं है) - लेकिन यह फिर भी बहुत ही उचित लगता है।

कोड:

पीसी आवेदन:

/*
stack_overflow
 - a quick program to force a stack overflow in order to see how many stack frames in a small function can be loaded onto the stack before the overflow occurs

By Gabriel Staples
www.ElectricRCAircraftGuy.com
Written: 6 Nov 2017
Updated: 6 Nov 2017

References:
 - Jumping into C++, by Alex Allain, pg. 230 - sample code here in the chapter on recursion

To compile and run:
Compile: g++ -Wall -std=c++11 stack_overflow_1.cpp -o stack_overflow_1
Run in Linux: ./stack_overflow_1
*/

#include <iostream>

void recurse(int count)
{
  std::cout << count << "\n";
  recurse(count + 1);
}

int main()
{
  recurse(1);
}

Arduino "स्केच" कार्यक्रम:

/*
recursion_until_stack_overflow
- do a quick recursion test to see how many times I can make the call before the stack overflows

Gabriel Staples
Written: 6 Mar. 2018 
Updated: 7 Mar. 2018 

References:
- Jumping Into C++, by Alex Allain, Ch. 16: Recursion, p.230
*/

// Force the compiler to NOT optimize! Otherwise this recursive function below just gets optimized into a count++ type
// incrementer instead of doing actual recursion with new frames on the stack each time. This is required since we are
// trying to force stack overflow. 
// - See here for all optimization levels: https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html
//   - They include: -O1, -O2, -O3, -O0, -Os (Arduino's default I believe), -Ofast, & -Og.

// I mention `#pragma GCC optimize` in my article here: http://www.electricrcaircraftguy.com/2014/01/the-power-of-arduino.html
#pragma GCC optimize ("-O0") 

void recurse(unsigned long count) // each call gets its own "count" variable in a new stack frame 
{
  // delay(1000);
  Serial.println(count);

  // It is not necessary to increment count since each function's variables are separate (so the count in each stack
  // frame will be initialized one greater than the last count)
  recurse (count + 1);

  // GS: notice that there is no base condition; ie: this recursive function, once called, will never finish and return!
}

void setup()
{
  Serial.begin(115200);
  Serial.println(F("\nbegin"));
  // First function call, so it starts at 1
  recurse (1);
}

void loop()
{
}

संदर्भ:

  1. एलेक्स एलेन , च 16: रिकर्सियन, पी .230 द्वारा सी ++ में कूदना
  2. http://www.electricrcaircraftguy.com/2014/01/the-power-of-arduino.html - शाब्दिक: मैंने इस "प्रोजेक्ट" के दौरान अपनी खुद की वेबसाइट को संदर्भित किया, यह याद दिलाने के लिए कि किसी दिए गए फ़ाइल के लिए Arduino संकलक अनुकूलन स्तर कैसे बदलें साथ #pragma GCC optimizeआदेश के बाद से मैं जानता था कि मैं इसे वहाँ दस्तावेज था।

1
ध्यान दें कि, avr-lib के डॉक्स के अनुसार, आपको कभी भी अनुकूलन के बिना किसी भी चीज़ का संकलन नहीं करना चाहिए जो avr-libc पर निर्भर करता है, क्योंकि कुछ चीज़ों की गारंटी नहीं दी जाती है, भले ही ऑप्टिमाइज़ेशन बंद कर दिया गया हो। इस प्रकार मैं आपको सलाह देता हूं कि #pragmaआप वहां उपयोग कर रहे हैं। इसके बजाय, आप __attribute__((optimize("O0")))जिस एकल फ़ंक्शन को अपनाना चाहते हैं , उसे जोड़ सकते हैं ।
एडगर बोनट

धन्यवाद, एडगर। क्या आप जानते हैं कि AVR libc ने यह दस्तावेज कहां दिया है?
गेब्रियल स्टेपल्स

1
<Util / delay.h> पर प्रलेखन राज्यों: "इरादा, संकलक अनुकूलन के रूप में काम करने के लिए इन कार्यों के लिए आदेश में होना चाहिए सक्रिय किया जा [...]" (मूल में जोर)। मुझे बिल्कुल यकीन नहीं है कि क्या किसी अन्य एवीआर-एफएमसी के कार्यों की यह आवश्यकता है।
एडगर बोनट

1

मैंने यह सरल परीक्षण कार्यक्रम लिखा:

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  recurse(1);
}

void loop() {
  // put your main code here, to run repeatedly: 

}

void recurse(long i) {
  Serial.println(i);
  recurse(i+1);
}

मैंने इसे यूनो के लिए संकलित किया, और जैसा कि मैंने लिखा है कि यह 1 मिलियन से अधिक बार पुन: प्राप्त हुआ है! मुझे नहीं पता, लेकिन संकलक ने इस कार्यक्रम को अनुकूलित किया हो सकता है


कॉल की एक निर्धारित संख्या के बाद लौटने की कोशिश करें ~ 1000। यह तो एक समस्या पैदा करनी चाहिए।
एशेश्र

1
कंपाइलर ने आपके स्केच पर चालाकी से पूंछ-पुनरावृत्ति लागू की है , जैसा कि आप देखेंगे कि क्या आप इसे अलग करते हैं। इसका मतलब यह है कि यह अनुक्रम call xxx/ retद्वारा प्रतिस्थापित करता है jmp xxx। यह एक ही चीज़ पर निर्भर करता है, सिवाय इसके कि संकलक की विधि स्टैक का उपभोग नहीं करती है। इस प्रकार आप अपने कोड के साथ अरबों बार पुनरावृत्ति कर सकते हैं (अन्य चीजें बराबर हैं)।
निक गैमन

आप कंपाइलर को पुनरावृत्ति का अनुकूलन नहीं करने के लिए बाध्य कर सकते हैं। मैं वापस आता हूं और बाद में एक उदाहरण पोस्ट करता हूं।
गैब्रियल स्टेपल्स

किया हुआ! उदाहरण यहाँ: arduino.stackexchange.com/a/51098/7727 । रहस्य #pragma GCC optimize ("-O0") आपके Arduino कार्यक्रम के शीर्ष पर जोड़कर अनुकूलन को रोकने के लिए है। मेरा मानना ​​है कि आपको ऐसा प्रत्येक फ़ाइल के शीर्ष पर करना होगा जिसे आप इसे लागू करना चाहते हैं - लेकिन मैंने वर्षों में ऐसा नहीं देखा है इसलिए यह सुनिश्चित करने के लिए अपने आप पर शोध करें।
गेब्रियल स्टेपल्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.