در دو مقالهی پیشین «نکات و ترفندهای بهینهسازی برنامه C برای میکروکنترلر AVR-قسمت اول» و «قسمت دوم» به معماری میکروکنترلرهای هشت بیتی AVR و کامپایلر GCC و نکات بهینه سازی حجم کد برنامه C پرداختیم. در مقاله پیش رو با نکات مربوط به کاهش زمان اجرای برنامه (execution time) برای بهینه سازی برنامه C آشنا میشویم.
نکات و ترفندهای کاهش زمان اجرای برنامه برای بهینه سازی برنامه C
1)انواع دادهها و اندازهی آنها
انتخاب نوع داده و اندازهی دادهی مناسب افزون بر کاهش حجم کد برنامه، زمان اجرا را نیز کاهش خواهد داد. برای میکروکنترلرهای هشت بیتی AVR، دسترسی به مقدار هشت بیتی، کارآمدترین روش است. در مثال زیر میتوانید تفاوت زمان اجرا را با دو متغیر هشت بیتی و 16بیتی مشاهده کنید.
2)دستورات شرطی
یادآوری: عملگر کاهش (Decrement Operator) مقدار یک متغیر را یک واحد کاهش میدهد. عملگر کاهش دارای دو نوع است. در صورتی که عملگر کاهش، بعد از متغیر بیاید، حاصل عبارت برابر با مقدار اولیهی متغیر میشود و به آن عملگر پسا-کاهش (post-decrement) گفته میشود. ولی در صورتی که این عملگر قبل از متغیر، استفاده شود، حاصل عبارت برابر با مقدار تغییر کردهی متغیر است. به این عملگر، عملگر پیش-کاهش (Pre-Decrement) گفته میشود.
معمولا عملگرهای پیش-کاهش (pre-decrement) یا پسا-کاهش (post-decrement) در کدهای عادی هیچ تفاوتی ندارند و کد یکسانی را تولید حواهند کرد. برای عملگرهای پیش-افزایش (pre-increment) یا پسا-افزایش (post-increment) نیز مشابه است. با این حال استفاده از این نوع عملگر به عنوان اندیس حلقهها و یا در دستورات شرطی کد متفاوتی تولید خواهد کرد.
شاید برای شما مفید باشد: میکروکنترلر مقصر نیست مقصر برنامه نویسی است
همانطور که در «قسمت اول-اندیس حلقهی تکرار» مشاهده کردیم، به کاربردن اندیس حلقه به صورت کاهشی، حجم کد کمتری را تولید خواهد کرد. استفاده از اندیسهای کاهشی در جملات شرطی به افزایش سرعت اجرا نیز کمک خواهد کرد.
از سوی دیگر در عملگر کاهشی، دو نوع عملگر پیش-کاهش و پسا-کاهش نیز نتایج متفاوتی تولید میکند. در مثال زیر خواهیم دید نوشتن جملهی شرطی با استفاده از عملگر پیش-کاهش، زمان اجرای کد را کاهش میدهد. مقدار Cycle Counter زمان اجرای طولانیترین حلقه را نشان میدهد. «loop_cnt» در دو مثال راست و چپ مقدار متفاوت دارد تا هر دو کد به صورت مشابه اجرا شود. در این کد در هر اجرا، PORTC0 به تعداد 9 بار و PORTB0 یک بار toggle میشوند.
3)باز کردن حلقه (Unrolling loops)
در برخی برنامهها برای افزایش سرعت اجرا از روش باز کردن حلقه استفاده میشود. این روش برای حلقههای کوتاه مناسب است. پس از اینکه یک حلقه باز (unrol) میشود، شرط حلقه برای چک کردن وجود ندارد و در هر مرحله اجرای حلقه، شاخههای کمتری اجرا میشوند. در مثال زیر یک پورت، 10 بار toggle میشود. همانطور که میبینید با باز کردن حلقه، سرعت اجرای برنامه افزایش مییابد. از طرفی حجم کد برنامه افزایش یافته است. این مثال توجه به تعادل میان حجم کد و سرعت برنامه را نشان میدهد. اگر کامپایلر از سطح بهینهسازی O3- استفاده کند به صورت خودکار حلقه را باز میکند.
4)جریان کنترل (Control flow) : دستورات if-else و switch-case
دستورات if-else و switch-case به طور گسترده در برنامهنویسی C کاربرد دارند. این دستورات یک روش مناسب برای کاهش زمان اجرای برنامه و بهینه سازی برنامه C به شمار میآیند. برای دستور if-else همیشه محتملترین شرط را در مکان اول بنویسید و شرط های با احتمال کمتر را در مکانهای بعدی دستور قرار دهید. با این کار در زمان اجرای برنامه صرفهجویی میشود.
به کارگیری دستور switch-case به جای if-else باعث میشود که کامپایلر lookup table تشکیل دهد و به مکان با شرط برقرار، پرش کند. اگر استفاده از دستور switch-case برای برنامهی موردنظر مشکل است میتوان از تعدادی if-else با زیر شاخههای کوچکتر استفاده کرد. این روش زمان اجرای برنامه را برای بدترین شرایط کاهش میدهد. در مثال زیر داده از ADC دریافت میشود و با USART ارسال میشود. در این مثال زمان اجرا کاهش یافته اما حجم کد زیاد شده است. بنابراین با توجه به شرایط موردنیاز، میان سرعت و حجم کد باید تعادل برقرار کنیم.
منبع: Atmel
خیلی جامع و خوب بود.واقعا ممنون
فقط یه سوال برام پیش اومد.چطور میشه بهبود عملکرد یه برنامه رو (چه از نظر حجم کد و چه از نظر تعداد سیکل اجرای برنامه) رو اندازه گیری کرد؟
آیا محیط توسعه gcc-base ای وجود داره که این اطلاعات رو راجع به برنامه در اختیارمون بذاره؟
ممنون میشم راهنماییم کنید.
خوب این اطلاعات رو راحت نمیشه به دست آورد خیلی از مسائل به تجربه بر میگرده و البته راه علمی اینه که کد های اسمبلی تولید شده رو بررسی کنید
البته خواندن منوال کامپایلر هم خیلی کمک میکنه 🙂
هر سه قسمت رو خوندم عالی بود و فوق العاده مورد نیاز واقعا دستتون درد نکنه
فقط اگه میشه تو قسمت منبع لینک مطلب اصلی رو بدید تا بتونیم از نسخه های دیگه اش هم استفاده کنیم
خواهش میکنم دوست عزیز
فکر میکنم یک از رفرنس منوال های آتمل هست که به این موضوع پرداخته