نکات و ترفندهای بهینه سازی برنامه C برای میکروکنترلر AVR -قسمت اول

blog
۱۳۹۶-۰۴-۲۲
5 دقیقه

هنگامی‌که درباره‌ی بهینه‌سازی برنامه C صحبت می‌کنیم، معمولاً به دو جنبه اشاره داریم: 1) حجم کد برنامه 2) سرعت اجرای برنامه.

کامپایلرهای امروزی C گزینه‌های متنوعی برای بهینه‌سازی برنامه C میکروکنترلر AVR در هر دو جنبه‌ی حجم و سرعت اجرای کد دارند. با این حال یک برنامه‌ با کدنویسی خوب این فرصت را برای کامپایلرها ایجاد می‌کند که کد را به بهترین حالت بهینه کنند. در برخی مواقع بهینه کردن کد برنامه در یک جنبه، تأثیر منفی بر جنبه‌ی دیگر دارد. بنابراین برنامه‌نویسان با توجه به نیازهای خاص خود باید بین این دو جنبه‌ی بهینه‌سازی، تعادل برقرار کنند.

دانستن نکات و ترفندهای بهینه‌سازی برنامه C میکروکنترلرهای هشت بیتی AVR به برنامه‌نویسان کمک می‌کند که برنامه‌ا‌ی با کارایی بالا داشته باشند. در این مقاله قصد داریم به همین نکات بپردازیم. اما پیش از بهینه‌ کردن برنامه‌های سیستم‌های تعبیه‌شده‌ی خود (embedded systems) نیاز است که درک درستی از معماری و ساختار هسته‌ی AVR داشته باشیم. همچنین باید بدانیم کامپایلر از چه ترفندهایی برای تولید بهینه‌ی کد استفاده می‌کند. با سیسوگ همراه باشید.

معماری میکروکنترلر هشت بیتی AVR

نکات و ترفندهای بهینه‌سازی کد C برای میکروکنترلرهای هشت بیتی AVR-قسمت اول

معماری هاروارد

یکی از ویژگی‌های مهم میکروکنترلر AVR، برخورداری از معماری هاروارد (HARVARD) است. در این معماری، داده و دستورالعمل در حافظه‌ای جداگانه قرار گرفته و همچنین از مسیرهای سیگنال جداگانه استفاده می‌کنند. میکروکنترلرهای AVR دارای 32 رجیستر کاری هشت بیتی هستند. این رجیسترها جزیی از حافظه‌ی داده به شمار می‌آیند. گفتنی است تعداد رجیسترهای کاری بر کارایی پردازنده تأثیر به سزایی دارد؛ چراکه دستورات منطقی و محاسباتی با رجیسترهای کاری کار می‌کنند.

شاید برای شما مفید باشد: میکروکنترلر مقصر نیست مقصر برنامه نویسی است

ALU می‌تواند در سیکل کلاک به یک زوج از رجیسترهای کاری دسترسی پیدا کند و با دو عملوند که در این دو رجیستر هستند دستورالعمل را اجرا کرده و نتیجه را به رجیستر مقصد بازگرداند. زمان اجرای دستورالعمل‌ها تنها یک سیکل کلاک است و در یک ساختار Pipeline فازهای اجرای دستورالعمل و واکشی به‌صورت موازی انجام می‌شود. حافظه‌ی برنامه به‌صورت 16 بیتی سازمان یافته‌اند و تمام دستورالعمل‌های AVR شانزده یا سی و دو بیت عرض دارند. در میکروکنترلرهای AVR، معماری ریسک (RISC) پیشرفته در راستای کاهش حجم کد برنامه و اجرای عملیات در یک سیکل کلاک و بهینه‌سازی برنامه C به کار گرفته شده است.

کامپایلر GCC

پیش‌پاز‌ این، در مقاله‌ی «کامپایلر Codevisionavr در مقابل کامپایلر GCC و مقایسه تخصصی آنها» با تفاوت‌ها و برتری کامپایلر GCC نسبت به کدویژن آشنا شدیم. در این مقاله‌‌ بر اساس کامپایلر GCC پیش می‌رویم با این حال همه‌‌ی نکات و ترفندها برای کامپایلرهای دیگر قابل‌اجرا است. کامپایلر GCC سطوح مختلف بهینه‌سازی را فراهم می‌کند. کامپایلر می‌تواند بهینه‌سازی را یا بر روی حجم کد و یا بر روی سرعت اجرای کد انجام دهد که این عمل در پنج سطح مختلف Os , -O3 , -O2 , -O1 , -O0- انجام می‌گردد. سطح O0- بدون انجام بهینه‌سازی است. در کنار این سطوح، گزینه‌های دیگری نیز برای انتخاب شرایط بهینه‌سازی موردنظر خود وجود دارد. در این لینک همه‌ی سطوح بهینه‌سازی به‌صورت کامل آورده شده است.

نکات و ترفندهای کاهش حجم برنامه برای بهینه‌سازی برنامه C

1) انواع داده‌ها و اندازه‌ی آن‌ها

از کوچک‌ترین نوع داده‌ی ممکن استفاده کنید. کد خود را از لحاظ انواع داده‌ی به‌کار رفته ارزیابی کنید. برای خواندن یک مقدار 8 بیتی به یک متغیر یک بایتی نیاز است نه متغیر دو بایتی. اندازه‌ی انواع داده‌ها در فایل هدر stdint وجود دارد.

نکات و ترفندهای بهینه‌سازی کد C برای میکروکنترلرهای هشت بیتی AVR-قسمت اول

انواع داده‌ها در میکروکنترلر AVR

در نمونه‌ی زیر مشاهده می‌کنیم که در مثال سمت چپ، نوع داده‌ی int دو بایتی و در مثال سمت راست نوع داده‌ی char یک بایتی تعریف شده است. همان‌طور که مشاهده می‌کنید از حافظه، دو بایت کمتر استفاده شده است:

نکات و ترفندهای بهینه‌سازی کد C برای میکروکنترلرهای هشت بیتی AVR-قسمت اول

2) متغیرهای عمومی (Global) و محلی (local)

در بیشتر موارد استفاده از متغیرهای عمومی توصیه نمی‌شود. تا جایی که ممکن است از متغیرهای محلی استفاده کنید. اگر یک متغیر تنها در یک تابع به‌کار می‌رود، آن را به‌صورت محلی در خود تابع تعریف کنید. اگر یک متغیر عمومی تعریف ‌شود، آدرس منحصر‌به‌فردی در حافظه‌ی SRAM به آن اختصاص داده می‌شود و مقدار آن در تمام مدت اجرای برنامه حفظ می‌شود. متغیرهای محلی برای همه‌ی توابع قابل‌استفاده نیستند و محلی از حافظه یا رجیستر کاری به آن اختصاص داده می‌شود و پس از خروج از تابع این فضا آزاد می‌شود.

در مثال سمت چپ متغیر عمومی و در مثال سمت راست متغیر محلی به کار رفته است. حجم اشغالی حافظه‌‌ی برنامه و داده نشان می‌دهد که متغیر محلی فضای کمتری از حافظه را اشغال می‌کند.

نکات و ترفندهای بهینه‌سازی کد C برای میکروکنترلرهای هشت بیتی AVR-قسمت اول

3) اندیس حلقه‌ی تکرار

همان‌طور که می‌دانیم، سه نوع حلقه‌ی تکرار while و for و do-while وجود دارد. اگر سطح بهینه‌سازی –Os فعال باشد، کامپایلر حلقه‌ها را به‌گونه‌ای بهینه می‌کند که حجم کد یکسانی داشته باشند. با این حال ما می‌توانیم با ترفندهایی، حجم کد را بیشتر کاهش دهیم. اگر از حلقه‌ی do-while در برنامه‌ی خود استفاده می‌کنیم، بسته به این‌که از اندیس افزایشی یا کاهشی تعریف می‌شود، اندازه‌ی کد متفاوتی ایجاد خواهد شد. ما به‌طور معمول در برنامه‌ها اندیس افزایشی را به‌کار می‌بریم. به این معنا که از مقدار صفر تا مقدار حداکثر افزایش می‌یابد. اما از نظر بهینه‎سازی کد بهتر است که از مقدار حداکثر تا صفر کاهش یابد؛ به این علت که در حلقه‌ی افزایشی، باید هر بار که حلقه‌ی تکرار اجرا می‌شود، مقدار اندیس با مقدار حداکثر حلقه که در بخش شرط حلقه‌ی تعریف‌شده، مقایسه شود. در حلقه‌ی کاهشی نیاز نیست که در هربار اجرای حلقه شرط حلقه چک شود زیرا مقدار اندیس اگر به صفر برسد، پرچم Z را در رجیستر وضعیت SREG یک می‌کند.

در مثال، تفاوت حجم اشغالی حافظه را در دو حالت حلقه‌ی کاهشی و افزایشی مشاهده می‌کنید.

نکات و ترفندهای بهینه‌سازی کد C برای میکروکنترلرهای هشت بیتی AVR-قسمت اول

4) تلفیق حلقه‌های تکرار

اگر حلقه‌های متفاوت، محدوده‌ی تکرار یکسان داشته باشند و از داده‌ی یکدیگر استفاده نکنند، می‌توانیم آن‌ها را تلفیق کرده و به یک حلقه‌ی واحد تبدیل کنیم تا تعداد حلقه‌ها را در برنامه کاهش دهیم. تلفیق حلقه‌ها به کاهش حجم کد و افزایش سرعت اجرای برنامه منجر می‌شود.

نکات و ترفندهای بهینه‌سازی کد C برای میکروکنترلرهای هشت بیتی AVR-قسمت اول

در قسمت‌های دیگر با نکات و ترفندهای بیشتری درباره‌ی کاهش حجم کد برنامه برای بهینه‌سازی برنامه C آشنا خواهیم شد. پس از آن به سراغ افزایش سرعت اجرای برنامه و کاهش زمان اجرا می‌رویم.

منبع: Atmel

اطلاعات
6
0
لینک و اشتراک
profile

Khatereh Akbari

متخصص الکترونیک

مقالات بیشتر
slide

پالت | بازار خرید و فروش قطعات الکترونیک

قطعات اضافه و بدون استفاده همیشه یکی از سرباره‌‌های شرکتها و طراحان حوزه برق و الکترونیک بوده و هست. پالت سامانه‌ای است که بصورت تخصصی اجازه خرید و فروش قطعات مازاد الکترونیک را فراهم می‌کند. فروش در پالت
family

آیسی | موتور جستجوی قطعات الکترونیک

سامانه آی سی سیسوگ (Isee) قابلیتی جدید و کاربردی از سیسوگ است. در این سامانه سعی شده است که جستجو، انتخاب و خرید مناسب تر قطعات برای کاربران تسهیل شود. وقتی شما در این سامانه، قطعه الکترونیکی را جستجو می‌کنید؛ آی سی به سرعت نتایج جستجوی شما در اکثر فروشگاه‌های آنلاین در حوزه قطعات الکترونیک را نمایش می‌دهد. جستجو در آیسی
family

فروشگاه سیسوگ

فروشگاه سیسوگ مجموعه ای متمرکز بر تکنولوژی های مبتنی بر IOT و ماژول های M2M نظیر GSM، GPS، LTE، NB-IOT، WiFi، BT و ... جایی که با تعامل فنی و سازنده، بهترین راهکارها انتخاب می شوند. برو به فروشگاه سیسوگ
family

سیسوگ فروم | محلی برای پاسخ پرسش‌های شما

دغدغه همیشگی فعالان تخصصی هر حوزه وجود بستری برای گفتگو و پرسش و پاسخ است. سیسوگ فروم یک انجمن آنلاین است که بصورت تخصصی امکان بحث، گفتگو و پرسش و پاسخ در حوزه الکترونیک را فراهم می‌کند. پرسش در سیسوگ فرم
become a writer

نویسنده شو !

سیسوگ با افتخار فضایی برای اشتراک گذاری دانش شماست. برای ما مقاله بنویسید.

ارسال مقاله
become a writer

نویسنده شو !

سیسوگ با افتخار فضایی برای اشتراک گذاری دانش شماست. برای ما مقاله بنویسید.

ارسال مقاله
خانواده سیسوگ

پالت | بازار خرید و فروش قطعات الکترونیک

قطعات اضافه و بدون استفاده همیشه یکی از سرباره‌‌های شرکتها و طراحان حوزه برق و الکترونیک بوده و هست. پالت سامانه‌ای است که بصورت تخصصی اجازه خرید و فروش قطعات مازاد الکترونیک را فراهم می‌کند.
family

آیسی | موتور جستجوی قطعات الکترونیک

سامانه آی سی سیسوگ (Isee) قابلیتی جدید و کاربردی از سیسوگ است. در این سامانه سعی شده است که جستجو، انتخاب و خرید مناسب تر قطعات برای کاربران تسهیل شود. وقتی شما در این سامانه، قطعه الکترونیکی را جستجو می‌کنید؛ آی سی به سرعت نتایج جستجوی شما در اکثر فروشگاه‌های آنلاین در حوزه قطعات الکترونیک را نمایش می‌دهد.
family

فروشگاه سیسوگ

فروشگاه سیسوگ مجموعه ای متمرکز بر تکنولوژی های مبتنی بر IOT و ماژول های M2M نظیر GSM، GPS، LTE، NB-IOT، WiFi، BT و ... جایی که با تعامل فنی و سازنده، بهترین راهکارها انتخاب می شوند.
family

سیسوگ فروم | محلی برای پاسخ پرسش‌های شما

دغدغه همیشگی فعالان تخصصی هر حوزه وجود بستری برای گفتگو و پرسش و پاسخ است. سیسوگ فروم یک انجمن آنلاین است که بصورت تخصصی امکان بحث، گفتگو و پرسش و پاسخ در حوزه الکترونیک را فراهم می‌کند.
family

دیدگاه ها

profile
سعید گفت :
۱۴۰۳-۱۰-۲۳ ۲۳:۵۶

خیلی ممنون عالی و کاملا قابل فهم توضیح دادید

profile
raghb گفت :
۱۳۹۶-۰۹-۰۵ ۲۱:۱۱

مهندس
دستتون درد نکنه
چرا در ID آردینو
وقتی یک متغییر گلوبال تعریف و استفاده میشه و وقتی آن را در داخل یک تابع بصورت لوکال استفاده می کنیم آردینو تغییری در اعلام میزان sram نمیده چرا؟

profile
زئوس Zeus گفت :
۱۳۹۶-۰۹-۲۲ ۰۸:۴۵

دلایل متفاوتی میتونه داشته باشه ، از جمله حوزه بندی و یا استفاده در اینتراپت و..
بهتره نمونه کد رو قرار بدید که بشه دلیلش رو توضیح داد.

profile
النا گفت :
۱۳۹۶-۰۵-۱۰ ۰۱:۴۳

این مقاله واقعا برای من مفید بود.
همیشه از استادهامون میشنیدیم که فلان کار باعث میشه در مصرف حافظه صرفه جویی بشه ولی چون نمونه نمیدیدیم خیلی رعایت نمیکردیم.
اما این تصاویر خیلی واضح این تاثیر این نکات رو نشون میداد.
خیلی ممنون از شما.

profile
علی گفت :
۱۳۹۶-۰۵-۰۵ ۰۲:۲۴

عالی بود مهندس. فکر نمی کردم انقدر ساده بشه بهینه سازی انجام داد. درواقع فکر نمی کردم مثلا شمارش افزایشی یا کاهشی انقدر موثر باشه.

خیلی ممنون ازینکه تجربه هاتونو در اختیار دیگران قرار میدید.

profile
Khatereh Akbari گفت :
۱۳۹۶-۰۵-۰۵ ۱۱:۴۷

خواهش میکنم. خوشحالم که این مقاله مورد توجه شما قرار گرفته.

become a writer

نویسنده شو !

سیسوگ با افتخار فضایی برای اشتراک گذاری دانش شماست. برای ما مقاله بنویسید.

ارسال مقاله
become a writer

نویسنده شو !

سیسوگ با افتخار فضایی برای اشتراک گذاری دانش شماست. برای ما مقاله بنویسید.

ارسال مقاله