আমি কত পুনরাবৃত্তি করতে পারি? আমি কত পুনরাবৃত্তি করতে পারি? কতটা সিএ! @ # কিউএফএসডি @। আরএফডাব্লু


19

আরডুইনো ইউনো বোর্ডের সীমিত র‌্যাম রয়েছে যার অর্থ এটির একটি সীমাবদ্ধ কল স্ট্যাক উপলব্ধ। কখনও কখনও, পুনরাবৃত্তি একটি নির্দিষ্ট অ্যালগরিদম বাস্তবায়নের একমাত্র দ্রুত বিকল্প। সুতরাং, কল স্ট্যাকটি মারাত্মকভাবে সীমাবদ্ধ রয়েছে, বোর্ডে চলমান একটি নির্দিষ্ট প্রোগ্রাম দেওয়ার পরে এটি সন্ধান করার উপায় কী হবে, স্ট্যাকের ওভারফ্লো হওয়ার আগে ঠিক কতগুলি পুনরাবৃত্ত কলগুলি বহন করতে পারে (এবং খারাপ জিনিসগুলি ঘটে)?


2
আপনি কি এমন একটি অ্যালগোরিদমের উদাহরণ দিতে পারেন যেখানে পুনরাবৃত্ত এবং অ-পুনরাবৃত্ত সমাধানের মধ্যে পছন্দটি এতটা পরিষ্কার কাট?
সাইবারবিবন্স

1
@ সাইবারিগিবনস সম্প্রতি, আমাকে স্বল্প সময়ের মধ্যে আরডিপি লিখতে এবং পরীক্ষা করতে হয়েছিল, তাই আমি পুনরাবৃত্তির বাস্তবায়নে এগিয়ে গেলাম। আমি বলছি না যে পুনরাবৃত্তি সম্ভব নয়, কেবল এটি পুনরাবৃত্ত সংস্করণ দিয়ে এগিয়ে যাওয়া সহজ হতে পারে।
asheeshr

কোন প্রশ্নের শিরোনামে মানে: How much ca!@#QFSD@$RFW? আমি কৌতূহল করছি যে কেন কেউ এটিকে সম্পাদন করেননি যে এটি আরও অর্থবহ কিছু হতে পারে (গত 4 বছরে)।
নিক গ্যামন

উত্তর 211বার (অনেক কারণের উপর নির্ভর করে) :)। আমার উত্তর এখানে দেখুন: arduino.stackexchange.com/a/51098/7727 । @ নিকগ্যামন, তিনি মনে করেন "অভিশাপ" দিচ্ছেন think এটি "পুনরাবৃত্তি" শব্দটির উপর একটি নাটক। এটাও বের করতে আমাকে এক মিনিট সময় নিয়েছে। প্রথমে বেশ বিভ্রান্তিকর ছিল।
গ্যাব্রিয়েল স্ট্যাপলস

আচ্ছা বুঝলাম. আমি ভেবেছিলাম এসই সার্ভারগুলিতে কোনও সমস্যা থাকতে পারে :)
নিক গ্যামন

উত্তর:


15

আপনি যদি সত্যিই পুনরাবৃত্তি করতে চান (এবং @ জিপ্পি বলেছিলেন এটি একটি খারাপ ধারণা; আক্ষেপের বার্তা: এটি করবেন না ) এবং আপনি কতটা পুনরাবৃত্তি করতে পারবেন তা জানতে চান, তবে আপনাকে কিছু গণনা এবং পরীক্ষা-নিরীক্ষা করতে হবে; এছাড়াও আপনার সাধারণভাবে এটির প্রায় একটি পরিমাণ থাকে কারণ এটি আপনার পুনরাবৃত্ত ক্রিয়াকলাপটি যখন ডাকা হবে তখন স্মৃতি অবস্থার উপর এটি অনেকটাই নির্ভর করে।

এর জন্য, আপনাকে প্রথমে জানতে হবে কীভাবে এসআরএএম অ্যাভিআর ভিত্তিক আরডুইনোর অভ্যন্তরে সংগঠিত হয় (এটি উদাহরণস্বরূপ ইন্টেলের দ্বারা আর্দুইনো গ্যালিলিওর ক্ষেত্রে প্রযোজ্য হবে না)। অ্যাডাফুর্টের নিম্নলিখিত চিত্রটি এটিকে পরিষ্কারভাবে দেখায়:

এসআরএএম সংগঠন

তারপরে আপনাকে আপনার এসআরএএম এর মোট আকার জানতে হবে (আটমেল এমসিইউর উপর নির্ভর করে, সুতরাং আপনার কী ধরণের আরডুইনো বোর্ড রয়েছে)।

এই চিত্রটিতে স্ট্যাটিক ডেটা ব্লকের আকার নির্ধারণ করা সহজ কারণ এটি সংকলন সময়ে জানা যায় এবং পরে পরিবর্তন হয় না।

গাদা আকার, যেমন রানটাইম এ পরিবর্তিত হতে পারে আরো জানতে কঠিন হতে পারে গতিশীল মেমরি বরাদ্দ (তার উপর নির্ভর করে mallocবা new) আপনার স্কেচ বা লাইব্রেরি এটি ব্যবহার করে দ্বারা সঞ্চালিত। ডায়ামিক মেমোরি ব্যবহার করা আরডুইনোতে বেশ বিরল, তবে কিছু মানক ফাংশন এটি করে (টাইপ Stringএটি ব্যবহার করে, আমি মনে করি)।

জন্য স্ট্যাক আকার, এটি ফাংশন কল বর্তমান গভীরতার উপর ভিত্তি করে রানটাইম সময় পরিবর্তিত হতে হবে, (প্রতিটি ফাংশন কল স্ট্যাক 2 বাইট নেয় আহ্বায়ক ঠিকানা সঞ্চয় করতে) এবং সংখ্যার এবং পাস আর্গুমেন্ট সহ স্থানীয় ভেরিয়েবল আকার ( এখন পর্যন্ত ডাকা সমস্ত ফাংশনগুলির জন্য যা স্ট্যাকের মধ্যেও সঞ্চিত রয়েছে ।

সুতরাং ধরা যাক আপনার recurse()ফাংশনটি তার স্থানীয় ভেরিয়েবল এবং আর্গুমেন্টগুলির জন্য 12 বাইট ব্যবহার করে, তারপরে এই ফাংশনটির প্রতিটি কল (বাহ্যিক কলার এবং পুনরাবৃত্তকারীগুলির প্রথমটি) 12+2বাইট ব্যবহার করবে ।

আমরা যদি ধরে নিই যে:

  • আপনি আরডুইনো ইউএনও-তে রয়েছেন (এসআরএএম = 2 কে)
  • আপনার স্কেচটি গতিশীল মেমরি বরাদ্দ ব্যবহার করে না (কোনও হিপ নেই )
  • আপনি আপনার স্ট্যাটিক ডেটার আকার জানেন (132 বাইট বলুন)
  • যখন আপনার recurse()স্কেচ থেকে আপনার ফাংশনটি কল করা হয়, বর্তমান স্ট্যাকটি 128 বাইট দীর্ঘ

তারপরে আপনাকে স্ট্যাকের2048 - 132 - 128 = 1788 উপলভ্য বাইটগুলি রেখে দেওয়া হবে । আপনার ক্রিয়াকলাপে পুনরাবৃত্ত কলগুলির সংখ্যা এইভাবে প্রারম্ভিক কল সহ (যা একটি পুনরাবৃত্তি নয়) including1788 / 14 = 127

আপনি দেখতে পাচ্ছেন যে এটি খুব কঠিন তবে আপনি যা চান তা খুঁজে পাওয়া অসম্ভব।

স্ট্যাকের আকারটি আগে উপলব্ধ হওয়ার সহজ উপায় recurse()হ'ল নিম্নোক্ত ফাংশনটি ব্যবহার করা (অ্যাডাফ্রুট শেখার কেন্দ্রে পাওয়া যায়; আমি নিজে এটি পরীক্ষা করি নি):

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

অ্যাডাফুর্ট লার্নিং সেন্টারে এই নিবন্ধটি পড়তে আমি দৃ strongly ়ভাবে উত্সাহ দিচ্ছি ।


আমি দেখছি পিটার-আর-ব্লুমফিল্ড আমার উত্তর লেখার সময় তার উত্তর পোস্ট করেছে; কোনও উত্তর দেওয়ার পরে স্ট্যাকের সামগ্রীটি সম্পূর্ণরূপে বর্ণনা করার সাথে তার উত্তরটি আরও ভাল দেখাচ্ছে (আমি রেজিস্ট্রারদের অবস্থা ভুলে গিয়েছিলাম)।
jfpoil ব্যাখ্যা

উভয়ই খুব ভাল মানের উত্তর।
সাইবারবিবন্স

স্ট্যাটিক ডেটা = .বিএস + .ডাটা এবং আরডুইনোর দ্বারা "গ্লোবাল ভেরিয়েবল দ্বারা র‌্যাম নেওয়া হয়েছে" বা যা কিছু সঠিক, তাই বলেছে?
গ্যাব্রিয়েল স্ট্যাপলস

1
@ গ্যাব্রিয়েল স্ট্যাপলস হ্যাঁ ঠিক আরও বিস্তারিতভাবে .bssআপনার কোডে কোনও প্রাথমিক মান ছাড়াই বৈশ্বিক ভেরিয়েবলগুলি উপস্থাপন করে, তবে dataপ্রাথমিক মান সহ গ্লোবাল ভেরিয়েবলের জন্য এটি রয়েছে। তবে শেষ পর্যন্ত তারা একই স্থান ব্যবহার করে: চিত্রটিতে স্ট্যাটিক ডেটা
jfpoil ব্যাখ্যা

1
@ গ্যাব্রিয়েল স্ট্যাপলস একটি জিনিস ভুলে গেছেন, প্রযুক্তিগতভাবে এগুলি কেবল গ্লোবাল ভেরিয়েবলগুলিই নয়, আপনি staticকোনও ফাংশনের মধ্যে ভেরিয়েবলগুলিও ঘোষণা করেছেন ।
jfpoil ব্যাখ্যা

8

ইতিমধ্যে নিজেকে বলে রেখেছেন পুনরাবৃত্তি একটি মাইক্রোকন্ট্রোলারের উপর খারাপ অনুশীলন এবং আপনি যখনই সম্ভব এটি এড়াতে চান। উপর যাও Arduino সাইটের কিছু উদাহরণ এবং লাইব্রেরী বিনামূল্যে র্যাম আকার চেক করার জন্য উপলভ্য নেই । উদাহরণস্বরূপ আপনি যখন আপনার স্কেচ এবং হার্ড কোডটিতে সীমাবদ্ধতাটি চিহ্নিত করতে পুনরাবৃত্তিটি ভাঙ্গবেন তখন কিছুটা কৌশল বা ঝুঁকিপূর্ণ figure আপনার প্রোফাইলের প্রতিটি পরিবর্তনের জন্য এবং আরডুইনো সরঞ্জাম চেইনের প্রতিটি পরিবর্তনের জন্য এই প্রোফাইলটির প্রয়োজন হবে।


আরও কিছু উচ্চ-সমাপ্ত সংকলক যেমন আইএআর (যারা এভিআর সমর্থন করে) এবং কেইল (যারা এভিআর সমর্থন করে না) তাদের কাছে স্ট্যাকের স্থান নিরীক্ষণ ও পরিচালনা করতে সহায়তা করার জন্য সরঞ্জাম রয়েছে। এটি এটিমেগা 328 এর মতো ছোট কিছুতে সত্যই পরামর্শ দেওয়া উচিত নয়।
সাইবারবিবন্স

7

এটি ফাংশনের উপর নির্ভর করে।

যতবারই কোনও ফাংশন ডাকা হয়, একটি নতুন ফ্রেম স্ট্যাকের দিকে ঠেলা যায়। এটিতে বিভিন্ন সমালোচনামূলক আইটেম থাকবে সাধারণত:

  • রিটার্ন ঠিকানা (কোডটির বিন্দু যা থেকে ফাংশন বলা হয়েছিল) Return
  • স্থানীয় thisফাংশন পয়েন্টার ( ) যদি কোনও সদস্য ফাংশন কল করে।
  • পরামিতিগুলি ফাংশনে প্রবেশ করেছে।
  • ফাংশন শেষ হয়ে গেলে পুনরুদ্ধার করা মানগুলি নিবন্ধ করুন।
  • কথিত ফাংশনের অভ্যন্তরে স্থানীয় ভেরিয়েবলের জন্য স্থান।

আপনি দেখতে পাচ্ছেন যে প্রদত্ত কলের জন্য প্রয়োজনীয় স্ট্যাকের জায়গাটি ফাংশনের উপর নির্ভর করে। উদাহরণস্বরূপ, আপনি যদি একটি পুনরাবৃত্ত ফাংশন লিখেন যা কেবলমাত্র intপ্যারামিটার নেয় এবং কোনও স্থানীয় ভেরিয়েবল ব্যবহার করে না, এটি স্ট্যাকের কয়েকটি বাইটের চেয়ে বেশি প্রয়োজন হবে না। এর অর্থ আপনি এটিকে ক্রিয়াকলাপভাবে কোনও ফাংশন থেকে অনেক বেশি কল করতে পারেন যা বেশ কয়েকটি পরামিতি নেয় এবং প্রচুর স্থানীয় ভেরিয়েবল ব্যবহার করে (যা স্ট্যাকটি আরও দ্রুত খেয়ে ফেলবে)।

স্পষ্টতই স্ট্যাকের অবস্থা কোডটিতে আর কী চলছে তার উপর নির্ভর করে। যদি আপনি সরাসরি স্ট্যান্ডার্ড loop()ফাংশনের মধ্যে একটি পুনরাবৃত্তি শুরু করেন , তবে সম্ভবত ইতিমধ্যে স্ট্যাকের উপরে খুব বেশি কিছু হবে না। তবে, আপনি যদি এটি অন্য ফাংশনগুলির গভীরে কয়েক স্তরের নেস্ট করে শুরু করেন, তবে এতটা জায়গা থাকবে না। এটি স্ট্যাকটি ক্লান্ত না করে আপনি কতবার পুনরাবৃত্তি করতে পারবেন তা প্রভাবিত করবে।

এটি লক্ষ্য করার মতো যে কিছু সংকলকগুলিতে টেল রিকার্সন অপটিমাইজেশন উপস্থিত রয়েছে (যদিও আমি নিশ্চিত নই যে এভিআর-জিসিসি এটি সমর্থন করে কিনা)। যদি পুনরাবৃত্তি কলটি কোনও ফাংশনে খুব শেষ জিনিস হয় তবে এর অর্থ হ'ল স্ট্যাক ফ্রেমের কোনও পরিবর্তন করা এড়ানো কখনও কখনও সম্ভব। সংকলকটি কেবল বিদ্যমান ফ্রেমটি পুনরায় ব্যবহার করতে পারে, যেহেতু 'প্যারেন্ট' কলটি (তাই বলতে) এটি ব্যবহার শেষ হয়েছে। এর অর্থ হ'ল আপনি তাত্ত্বিকভাবে আপনার পছন্দ অনুযায়ী পুনরাবৃত্তি চালিয়ে যেতে পারেন, যতক্ষণ আপনার ফাংশনটি অন্য কোনও কল না করে।


1
avr-gcc টেল পুনরাবৃত্তি সমর্থন করে না।
asheeshr

@ আখেশআর - জেনে রাখা ভাল। ধন্যবাদ। আমি অনুভব করেছি এটি সম্ভবত সম্ভাবনা ছিল।
পিটার ব্লুমফিল্ড

সংকলকটি এটি করবে আশা করে না করে আপনি আপনার কোডটি রিফ্যাক্ট করে একটি টেল কল এলিমিনেশন / অপ্টিমাইজেশন করতে পারেন। যতক্ষণ না পুনরাবৃত্তির কলটি পুনরাবৃত্ত পদ্ধতির শেষে থাকবে আপনি কিছুক্ষণ / লুপের জন্য পদ্ধতিটি নিরাপদে পুনরায় লিখতে পারবেন।
অ্যাবাস্টারফিল্ড

1
@ ডক্টর পোস্টটি "এভিআর-জিসিসি লেজ পুনরাবৃত্তি সমর্থন করে না" তার বিপরীত, যেমন আমার কোড হিসাবে তার পরীক্ষা করে। সংকলক প্রকৃতপক্ষে লেজ পুনরাবৃত্তি বাস্তবায়ন করেছিল, এভাবেই তিনি এক মিলিয়ন পুনরাবৃত্তি অর্জন করেছিলেন। পিটার সঠিক - সংকলকটির পক্ষে কল / রিটার্ন (কোনও ফাংশনের সর্বশেষ কল হিসাবে) কেবল লাফ দিয়ে প্রতিস্থাপন করা সম্ভব । এটির সমাপ্তি ফলাফল রয়েছে এবং স্ট্যাক স্পেস ব্যবহার করে না।
নিক গ্যামন

2

অ্যালেক্স অ্যালায়েন , সিএফ 16: রিকার্সন, পি .২৩০ লিখে সি ++ এ জাম্পিংয়ের সময় আমার ঠিক একই প্রশ্নটি ছিল , তাই আমি কিছু পরীক্ষা চালিয়েছি ran

TLDR;

আমার আরডুইনো ন্যানো (এটিএমগা 328 এমসিইউ) 211 পুনরাবৃত্ত ফাংশন কল করতে পারে (নীচে দেওয়া কোডটির জন্য) এটি স্ট্যাকের ওভারফ্লো এবং ক্র্যাশ হওয়ার আগে।

প্রথমে, আমাকে এই দাবিটি সম্বোধন করতে দাও:

কখনও কখনও, পুনরাবৃত্তি একটি নির্দিষ্ট অ্যালগরিদম বাস্তবায়নের একমাত্র দ্রুত বিকল্প।

[আপডেট: আহ, আমি "দ্রুত" শব্দটি স্কিমেড করেছি। সেক্ষেত্রে আপনার কিছুটা বৈধতা আছে। তবুও, আমি মনে করি এটি নীচেরটি বলা ভাল]]

না, আমি মনে করি না যে এটি সত্য বক্তব্য। আমি প্রায় কিছু না সব আলগোরিদিম উভয় একটি recursive এবং একটি অ-recursive সমাধান আছে, ব্যতিক্রম ছাড়া। এটি কেবলমাত্র কখনও কখনও এটি উল্লেখযোগ্যভাবে সহজপুনরাবৃত্তির অ্যালগরিদম ব্যবহার করতে। এই বলে যে, পুনরাবৃত্তি মাইক্রোকন্ট্রোলারগুলির জন্য ব্যবহারের জন্য অত্যন্ত উদ্বেগজনক এবং সেফটি-ক্রিটিকাল কোডে সম্ভবত কখনও অনুমতি দেওয়া হবে না। তবুও, এটি অবশ্যই মাইক্রোকন্ট্রোলারগুলিতে করা সম্ভব। আপনি যে কোনও "রিকার্সিভ ফাংশনে যেতে" গভীর "তা জানতে, কেবল এটি পরীক্ষা করুন! একটি বাস্তব-জীবন পরীক্ষার ক্ষেত্রে এটি আপনার বাস্তব-জীবনে প্রয়োগ করুন এবং আপনার বেস শর্তটি সরিয়ে দিন যাতে এটি অনন্তর পুনরাবৃত্তি হয়। একটি কাউন্টার মুদ্রণ করুন এবং নিজের জন্য দেখুন আপনি কীভাবে "গভীর" যেতে পারেন যাতে আপনি জানেন যে আপনার পুনরাবৃত্তির অ্যালগোরিদম আপনার র্যামের সীমাটিকে কার্যতভাবে ব্যবহারের খুব কাছাকাছি ঠেলে দিচ্ছে কিনা। একটি আরডুইনোতে স্ট্যাক ওভারফ্লো জোর করতে নীচের উদাহরণ এখানে।

এখন, কয়েকটি নোট:

আপনি যে কতগুলি পুনরাবৃত্ত কল বা "স্ট্যাক ফ্রেম" পেতে পারেন তা বিভিন্ন কারণের দ্বারা নির্ধারিত হয়, যার মধ্যে রয়েছে:

  • আপনার র‌্যামের আকার
  • ইতিমধ্যে আপনার স্ট্যাকের মধ্যে কী পরিমাণ স্টাফ রয়েছে বা আপনার স্তূপে নেওয়া হয়েছে (যেমন: আপনার নিখরচায় র‌্যামের বিষয়; free_RAM = total_RAM - stack_used - heap_usedবা আপনি বলতে পারেন free_RAM = stack_size_allocated - stack_size_used)
  • প্রতিটি নতুন "স্ট্যাক ফ্রেম" এর আকার যা প্রতিটি নতুন পুনরাবৃত্ত ফাংশন কলের জন্য স্ট্যাকের উপরে স্থাপন করা হবে। এটি কল করা ফাংশন এবং এর ভেরিয়েবল এবং মেমরির প্রয়োজনীয়তা ইত্যাদির উপর নির্ভর করবে etc.

আমার ফলাফল:

  • 20171106-2054 ঘন্টা - তোশিবা স্যাটেলাইট ডাব্লু / 16 জিবি র‌্যাম; কোয়াড-কোর, উইন্ডোজ 8.1: ক্র্যাশের আগে চূড়ান্ত মানটি মুদ্রিত: 43166
    • ক্রাশ হতে কয়েক সেকেন্ড সময় নিয়েছিল - সম্ভবত 5 ~ 10?
  • 20180306-1913 ঘন্টা ডেল উচ্চ-শেষ ল্যাপটপ ডাব্লু / 64 জিবি র‌্যাম; 8-কোর, লিনাক্স উবুন্টু 14.04 এলটিএস: ক্রাশের আগে মুদ্রিত চূড়ান্ত মান: 261752
    • শব্দগুচ্ছের পরে Segmentation fault (core dumped)
    • ক্র্যাশ করতে কেবল ~ 4 ~ 5 সেকেন্ড সময় নিয়েছিল
  • 20180306-1930 ঘন্টা আরডুইনো ন্যানো: টিবিডি --- ~ 250000 এ এখনও গণনা করছে --- আরডুইনো অপটিমাইজেশন সেটিংস অবশ্যই এটি পুনরাবৃত্তিটি অপ্টিমাইজ করার জন্য করেছে ... ??? হ্যাঁ, এটি ক্ষেত্রে।
    • যোগ #pragma GCC optimize ("-O0")ফাইল এবং পুনরায় শীর্ষে:
  • 20180307-0910 ঘন্টা আরডুইনো ন্যানো: 32 কেবি ফ্ল্যাশ, 2 কেবি এসআরএএম, 16 মেগাহার্টজ প্রসেসর: ক্রাশের আগে চূড়ান্ত মান মুদ্রিত: 211 Here are the final print results: 209 210 211 ⸮ 9⸮ 3⸮
    • এটি 115200 সিরিয়াল বাউড-রেটে মুদ্রণ শুরু করার পরে মাত্র এক সেকেন্ডের ভগ্নাংশ নিয়েছিল - সম্ভবত 1-10 সেকেন্ড
    • 2 কিবি = 2048 বাইট / 211 স্ট্যাক ফ্রেম = 9.7 বাইট / ফ্রেম (ধরে নিলে আপনার সমস্ত র‌্যাম স্ট্যাকটি ব্যবহার করছে - যা আসলে তা নয়) - তবে এটি তবে খুব যুক্তিসঙ্গত বলে মনে হয়।

কোড:

পিসি অ্যাপ্লিকেশন:

/*
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);
}

আরডুইনো "স্কেচ" প্রোগ্রাম:

/*
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.electricrcairraftguy.com/2014/01/the-power-of-arduino.html - আক্ষরিক: একটি প্রদত্ত ফাইলের জন্য কীভাবে আরডুইনো সংকলক অপ্টিমাইজেশন স্তর পরিবর্তন করতে হবে তা আমাকে স্মরণ করিয়ে দেওয়ার জন্য আমি এই "প্রকল্প" এর সময় আমার নিজের ওয়েবসাইটটি উল্লেখ করেছি সঙ্গে #pragma GCC optimizeকমান্ড যেহেতু আমি জানতাম আমি সেখানে নথিভুক্ত ছিল।

1
নোট করুন, অ্যাভরি-লিবের ডক্স অনুসারে, আপনার কখনই অপ্টিমাইজেশন ছাড়াই সংকলন করা উচিত নয় যা এভিআর-লিবিসি-র উপর নির্ভর করে, কারণ কিছু জিনিস এমনকি অপ্টিমাইজেশন বন্ধ হয়ে যাওয়ার সাথেও কাজ করার গ্যারান্টিযুক্ত নয়। আপনি #pragmaসেখানে ব্যবহার করছেন এর বিরুদ্ধে আমি আপনাকে পরামর্শ দিচ্ছি । পরিবর্তে, আপনি যোগ করতে পারেন __attribute__((optimize("O0")))থেকে একক কার্যকারিতা আপনি unoptimize করতে চাই।
এডগার বোনেট

ধন্যবাদ, এডগার আপনি কি জানেন যে AVR libc এর নথিটি রেখেছে?
গ্যাব্রিয়েল স্টেপলস

1
<ব্যবহার / দেরী। 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 মিলিয়নেরও বেশি বার পুনরাবৃত্তি হয়েছে! আমি জানি না, তবে সংকলকটি এই প্রোগ্রামটি অনুকূলিত করতে পারে


Number 1000 কলের একটি সেট সংখ্যার পরে ফিরে আসার চেষ্টা করুন। এটি তখন একটি সমস্যা তৈরি করা উচিত।
asheeshr

1
সংকলকটি চূড়ান্তভাবে আপনার স্কেচে পুচ্ছ-পুনরাবৃত্তি প্রয়োগ করেছে , আপনি দেখতে পাবেন যে আপনি এটি আলাদা করে রেখেছেন কিনা। এর অর্থ কী এটি ক্রমটি call xxx/ retদ্বারা প্রতিস্থাপন করে jmp xxx। এটি একই জিনিসটির সমতুল্য, কম্পাইলারের পদ্ধতিটি স্ট্যাকটি গ্রাস করে না except এইভাবে আপনি আপনার কোডের সাথে কয়েক মিলিয়ন বার পুনরাবৃত্তি করতে পারেন (অন্যান্য জিনিস সমান হচ্ছে)।
নিক গ্যামন

আপনি সংকলককে পুনরাবৃত্তিটি অপ্টিমাইজ না করার জন্য বাধ্য করতে পারেন। আমি ফিরে এসে একটি উদাহরণ পোস্ট করব।
গ্যাব্রিয়েল স্টেপলস

সম্পন্ন! উদাহরণ এখানে: arduino.stackexchange.com/a/51098/7727 । গোপনীয়তা হল #pragma GCC optimize ("-O0") আপনার আরডুইনো প্রোগ্রামের শীর্ষে যুক্ত করে অপ্টিমাইজেশন প্রতিরোধ করা । আমি বিশ্বাস করি যে এটি প্রয়োগ করতে চান এমন প্রতিটি ফাইলের শীর্ষে আপনাকে এটি করতে হবে - তবে আমি নিশ্চিত হয়েছি যে এটি বছরের পর বছর ধরে এটি গবেষণা করে না।
গ্যাব্রিয়েল স্টেপলস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.