লুপের ভিতরে একটি অসীম লুপ () দ্রুত সঞ্চালন করতে পারে?


19

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

এড়াতে, আপনি সম্ভবত নিজের অসীম লুপটি তৈরি করতে পারেন:

void loop()
{
    while (true)
    {
        // do stuff...
    }
}

কর্মক্ষমতা উন্নত করার কি এটি একটি কার্যকর উপায়? loop()কখনও ফিরে না এলে তা কি অন্যান্য সমস্যার সৃষ্টি করবে ?

উত্তর:


18

এটিএমগা কোরের কোডটির যে অংশটি সেটআপ () এবং লুপ () করে তা নীচে:

#include <Arduino.h>

int main(void)
{
        init();

#if defined(USBCON)
        USBDevice.attach();
#endif

        setup();

        for (;;) {
                loop();
                if (serialEventRun) serialEventRun();
        }

        return 0;
}

খুব সহজ, তবে সিরিয়ালএভেন্টরুন () এর ওভারহেড রয়েছে; সেখানে.

দুটি সহজ স্কেচ তুলনা করা যাক:

void setup()
{

}

volatile uint8_t x;

void loop()
{

    x = 1;

}

এবং

void setup()
{

}

volatile uint8_t x;

void loop()
{
    while(true)
    {
        x = 1;
    }
}

এক্স এবং অস্থির এটি অপ্টিমাইজড না হয়েছে তা নিশ্চিত করার জন্য।

উত্পাদিত এএসএম-এ, আপনি বিভিন্ন ফলাফল পাবেন: দুটি তুলনা

আপনি যখন দেখতে পাচ্ছেন (সত্য) কেবল কিছু নির্দেশাবলীতে একটি আরজেএমপি (আপেক্ষিক জাম্প) সম্পাদন করে, যেখানে লুপ () একটি বিয়োগ, তুলনা এবং কল সম্পাদন করে। এটি 4 টি নির্দেশাবলী বনাম 1 নির্দেশনা।

উপরের মতো ASM উত্পন্ন করতে আপনার avr-objdump নামে একটি সরঞ্জাম ব্যবহার করতে হবে। এটি avr-gcc এর সাথে অন্তর্ভুক্ত। ওএসের উপর নির্ভর করে লোকেশন পরিবর্তিত হয় তাই নাম অনুসারে এটি অনুসন্ধান করা সবচেয়ে সহজ।

avr-objdump .hex ফাইলগুলিতে অপারেট করতে পারে তবে এগুলি আসল উত্স এবং মন্তব্যগুলি অনুপস্থিত। যদি আপনি সবেমাত্র কোডটি তৈরি করেছেন, আপনার কাছে একটি। ফাইল ফাইল থাকবে যা এই ডেটা ধারণ করে না। আবার, এই ফাইলগুলির অবস্থান ওএস অনুসারে পরিবর্তিত হয় - এগুলি সনাক্ত করার সহজতম উপায় হল পছন্দগুলিতে ভার্বোস সংকলন চালু করা এবং আউটপুট ফাইলগুলি কোথায় সংরক্ষণ করা হচ্ছে তা দেখুন।

কমান্ডটি নিম্নলিখিতভাবে চালান:

avr-objdump -S আউটপুট.এলটি> asm.txt

এবং একটি পাঠ্য সম্পাদক এ আউটপুট পরীক্ষা করুন।


ঠিক আছে, তবে সিরিয়ালEventRun () ফাংশন কল করার কোনও কারণ নেই? এটি কিসের জন্যে?
jfpoil ব্যাখ্যা

1
এটি হার্ডওয়্যারশিরাল দ্বারা ব্যবহৃত কার্যকারিতার অংশ, নিশ্চিত না যখন সিরিয়াল যখন প্রয়োজন হয় না তখন এটি কেন নেওয়া হয় না।
সাইবারবিবন্স

2
আপনি কীভাবে এএসএম আউটপুট তৈরি করেছেন তা সংক্ষেপে ব্যাখ্যা করতে সহায়ক হবে যাতে লোকেরা তাদের পরীক্ষা করতে পারে।
জিপ্পি

@ সাইবারিগিবনস এটি কখনই আউট করা হয় না কারণ এটি আরডুইনো main.cআইডিই দ্বারা ব্যবহৃত মানের অংশ part তবে এর অর্থ এই নয় যে হার্ডওয়্যারশিরিয়াল লাইব্রেরিটি আপনার স্কেচে অন্তর্ভুক্ত রয়েছে; আসলে অন্তর্ভুক্ত করা হয় না যদি আপনি এটি ব্যবহার করবেন না (যে কেন নেই এর if (serialEventRun)মধ্যে main()ফাংশন আপনি ব্যবহার না করেন তাহলে HardwareSerial গ্রন্থাগার তারপর। serialEventRunনাল হতে হবে, অত কোন কল।
jfpoilpret

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

6

সাইবার্বিবনসের উত্তরটি চমত্কারভাবে সমাবেশ কোড জেনারেশন এবং দুটি কৌশলগুলির মধ্যে পার্থক্য বর্ণনা করে। এটি ব্যবহারিক পার্থক্যের ক্ষেত্রে ইস্যুটিকে দেখার পরিপূরক জবাব হিসাবে চিহ্নিত করা হয়েছে , অর্থাত্ কার্যকর করার সময়ের ক্ষেত্রে উভয় ক্ষেত্রেই কতটা তাত্পর্য হবে ।


কোডের বিভিন্নতা

আমি নিম্নলিখিত বিভিন্নতা জড়িত একটি বিশ্লেষণ করেছি :

  • বেসিক void loop()(যা সংকলনের সাথে মিলিত হয়)
  • আন-ইনলাইনড void loop()(ব্যবহার করা __attribute__ ((noinline)))
  • সাথে লুপ while(1)(যা অনুকূলিত হয়)
  • অপ-অনুকূলিতকরণযুক্ত লুপ while(1)(যোগ করে __asm__ __volatile__("");এটি একটি nopনির্দেশ যা কোনও volatileভেরিয়েবলের অতিরিক্ত ওভারহেডের ফলস্বরূপ লুপটির অনুকূলিতকরণকে বাধা দেয় )
  • void loop()অনুকূলিতকরণ সহ একটি আন-ইনলাইনডwhile(1)
  • অপ void loop()-অনুকূলিত সঙ্গে একটি আন-ইনলাইনডwhile(1)

স্কেচগুলি এখানে পাওয়া যাবে

পরীক্ষা

আমি এই স্কেচগুলির প্রত্যেকটি 30 সেকেন্ডের জন্য চালিয়েছি, যার ফলে প্রতিটিতে 300 টি ডেটা পয়েন্ট জমা হয়delayপ্রতিটি লুপে 100 মিলিসেকেন্ড কল ছিল (যা ছাড়াই খারাপ জিনিস ঘটে )।

ফলাফল

আমি তারপরে প্রতিটি লুপের গড় প্রয়োগের সময় গণনা করেছি, প্রতিটি থেকে 100 মিলিসেকেন্ড বিয়োগ করে ফলাফলগুলি প্লট করেছি।

http://raw2.github.com/AsheeshR/Arduino-Loop-Analysis/master/Figures/timeplot.png

উপসংহার

  • এর মধ্যে একটি অপ-অপ্টিমাইজড while(1)লুপটি void loopসংকলক অনুকূলিতকরণের চেয়ে দ্রুত void loop
  • অপ-অপ্টিমাইজড কোড এবং ডিফল্ট আরডুইনো অপ্টিমাইজড কোডের মধ্যে সময়ের পার্থক্যটি কার্যতভাবে তুচ্ছ । আপনি avr-gccনিজের সাহায্য করার জন্য আরডুইনো আইডিইয়ের উপর নির্ভর করে নিজের নিজের অপ্টিমাইজেশন ফ্ল্যাগগুলি ম্যানুয়ালি ব্যবহার এবং ব্যবহারের মাধ্যমে সংকলন করা ভাল (যদি আপনার মাইক্রোসেকেন্ড অপটিমাইজেশন প্রয়োজন হয়)।

দ্রষ্টব্য: এখানে প্রকৃত সময়ের মানগুলি তাত্পর্যপূর্ণ নয়, তাদের মধ্যে পার্থক্য। সঞ্চালনের সময় এর ~ 90 মাইক্রোসেকেন্ড একটি কল অন্তর্ভুক্ত Serial.println, microsএবং delay

দ্রষ্টব্য: এটি আরডুইনো আইডিই এবং এটি সরবরাহ করে এমন ডিফল্ট সংকলক পতাকা ব্যবহার করে করা হয়েছিল।

দ্রষ্টব্য: আর এর সাহায্যে বিশ্লেষণ (প্লট এবং গণনা) করা হয়েছিল।


1
ভাল কাজ. গ্রাফের মিলিসেকেন্ড রয়েছে মাইক্রোসেকেন্ড নয় তবে বিশাল সমস্যা নয়।
সাইবারবিবন্স

@ সাইবার্গিবনস যেহেতু সমস্ত পরিমাপ মাইক্রোসেকেন্ডে রয়েছে তেমন সম্ভাবনা কম এবং আমি কোথাও '
স্কেল'ও
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.