قبلاً در مقاله‌ای تحت عنوان “چرا کدویژن نه!” به بررسی شبه کامپایلر کدویژن و ناکارآمدی آن پرداختیم. مقاله مذکور بیش‌تر با محوریت قابلیت‌های استاندارد یک کامپایلر بود که کدویژن آنها را نداشت و به عملکرد واقعی کدویژن پرداخته نشده بود. در این مقاله می‌خواهیم در رابطه با بهترین کامپایلر AVR صحبت کنیم.

با چند تن از دوستان در خصوص همین مسئله تبادل‌نظر داشتیم. دوستان معتقد بودند که کدویژن در کامپایل و بهینه‌سازی کدِ خروجی خیلی موفق‌تر از GCC عمل می‌کند و در استاندارد نبودن آن مهم نیست و بهینه بودن کدِ خروجی از درجه اهمیت بالاتری برخوردار است. هرچند به نظر بنده، استاندارد بودن از درجه اهمیت بالاتری برخوردار است؛ چراکه کد قابل‌حمل و توسعه می‌شود. اگر کد شما قابل‌حمل باشد، برای انتقال آن از AVR به ARM نیازی به بازنویسی و حذف بخش‌های غیراستاندارد نیست.

از طرفی برتری داشتن یک شبه کامپایلر که توسط یک شرکت با تعداد افراد محدود ایجاده شده، از یک کامپایلر اپن سورس که جامعه‌ای از برنامه‌نویسان آزاد برای توسعه آن‌وقت گذاشته‌اند، قابل‌پذیرش نیست. ولی از آنجایی‌که هیچ ‌چیز غیرممکن نیست، حتی خود غیرممکن (!) قرار بر این شد که قابلیت اپتیمایز کد و همچنین سرعت اجرای کد ایجادشده توسط این دو کامپایلر را بررسی کنیم تا بتوان راحت‌تر در خصوص آن‌ها قضاوت کرد.

در ادامه به بررسی دو کامپایلر Codevision و GCC خواهیم پرداخت. پس با سیسوگ همراه باشید.

سخت‌افزار

برای انجام تست‌ها نیاز به یک سخت‌افزار پایه است که کدهای ایجادشده توسط هر کامپایلر را بر روی آن پروگرام کرد و بتوان نتیجه آن را مشاهده کرد. برای همین منظور ما از برد آردوینو Nano به‌عنوان سخت‌افزار استفاده کردیم.

این برد از پردازنده Atmega328p استفاده می‌کند که توسط کریستال 16 مگاهرتز کلاک آن تأمین می‌شود. برای این‌که بتوان نتیجه را ملموس‌تر احساس کرد، فرکانس کاری میکرو را با تقسیم فرکانس ورودی بر 16 به یک مگاسیکل کاهش دادیم. در تمام برنامه‌ها برای اندازه‌گیری سرعت اجرای برنامه، به کمک یک لاجیک آنالایز، سرعت صفر و یک شدن پایه PORTB.4 را اندازه‌گیری می‌کنیم که درواقع ملاکی از سرعت اجرای برنامه است؛ هرچه این پایه با سرعت بیشتری صفر و یک شود یعنی سرعت اجرای برنامه بیشتر و عملکرد کامپایلر در کامپایل کد بهتر است.

بهترین کامپایلر AVR

ما برای اینکه متوجه بشویم بهترین کامپایلر AVR چیست، از کامپایلر کدویژن ورژن 3.12،

 

و از کامپایلر GCC ورژن 3.5 به‌عنوان کامپایلر GCC استفاده کرده‌ایم.

 

 

شرایط یکسان برای کامپایلرها

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

 

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

 

برنامه تست اول:

در این برنامه خروجی Toggle شده و از هیچ تأخیری هم استفاده نشده است.

دقت داشته باشید که دو خط اول برنامه برای تنظیم تقسیم‌کننده‌ی ورودی است که فرکانس 16 مگاهرتز را به 1 مگاهرتز کاهش دهد.

 

برنامه تست دوم:

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

 

برنامه تست سوم:

در این برنامه علاوه بر تغییر وضعیت خروجی، یک سری عملیات ریاضی و منطقی بر روی متغیرهای 32 بیتی انجام‌شده به همراه فراخواندن یک متد.

 

برنامه تست چهارم:

این برنامه همانند برنامه سوم است، با این تفاوت که عملیات ریاضی و منطقی بر روی متغیرهای 64 بیتی انجام شده است.

 

برنامه تست پنجم :

در این برنامه یک سری عملیات ریاضی بر روی متغیرها انجام‌ شده و هم زمان خروجی تغییر وضعیت داده شده است.

خب کم کم داریم به جواب این سوال  که بهترین کامپایلر AVR چه کامپایلری است نزدیک می‌شویم با سیسوگ همراه باشید.

 

نتایج:

حجم برنامه:

 

 

نمودار فوق نشان‌دهنده‌ی حجم خروجی کامپایلر برای هر یک از برنامه‌ها است. نمودار نارنجی مربوط به کامپایلر کدویژن و نمودار آبی مربوط به کامپابلر GCC است. دقت داشته باشید هر چه برنامه با حجم کمتری ایجاد شده باشد، بهینه‌تر است؛ چراکه شما قادر هستید برنامه‌ی بیشتری را روی حافظه‌ی مشخصی ذخیره کنید. پس نمودار کوچک‌تر یعنی عملکرد بهتر.

دقت داشته باشید شبه کامپایلر کدویژن اصلاً قادر به کامپایل کد نمونه 4 نبود. چراکه این شبه کامپایلر، از متغیرهای 64 بیتی پشتیبانی نمی‌کند.

 

 

همانطور که از نتایج به دست آمده مشخص است، در این بخش، کامپایلر GCC به صورت 100 درصد عملکرد بهتری نسبت به شبه کامپایلر کدویژن دارد.

سرعت اجرا :

 

 

نمودار آبی مربوط به کامپایلر GCC و نمودار نارنجی مربوط به شبه کامپایلر کدویژن است. جواب‌ها، فرکانس ایجادشده بر روی خروجی است و واحد آن کیلوهرتز است. جواب برنامه‌های 2 و 3 و 4 در 10 و 100 ضرب شده‌اند تا در نمودار به خوبی مشخص باشند. هرچه مقدار این نمودار بیشتر باشد، نشان‌دهنده‌ی عملکرد بهتر کامپایلر است چراکه قادر است در واحد زمان تعداد کدهای بیشتری را اجرا کند.

توضیح در خصوص جواب برنامه 5 و اختلاف فاحش آن :

کامپایلر GCC دارای هوشمندی زیادی در اپتیمایز کد است. این کامپایلر با تشخیص قسمت‌های غیرضروری در برنامه و حذف آن‌ها، هم سرعت اجرا بالا می‌برد و هم در حافظه‌ی برنامه صرفه‌جویی می‌کند. اگر دقت کنید در برنامه شماره 5 یک سری عملیات ریاضی روی سه متغیر aaa و bbb و ccc انجام شده است که نتیجه عملیات فوق هیچ جا مورداستفاده قرار نگرفته است؛ به همین دلیل کامپایلر این عملیات را غیرضروری فرض و تمام روال آن را از برنامه حذف کرده است. به همین دلیل سرعت و حجم برنامه شماره 5 و 1 یکی است. اما شبه کامپایلر کدویژن دارای این هوشمندی نیست و نمی‌تواند قسمت‌های غیرضروری برنامه را تشخیص دهد و آن‌ها را حذف کند.

 

بهترین کامپایلر AVR کدام است؟

 

 

همان‌طور که انتظار می‌رفت کامپایلر GCC در تمام موارد عملکردی به‌مراتب بهتری از شبه کامپایلر کدویژن دارد. یکی از دلایل موفقیت صد درصدی کامپایلر GCC، متن‌باز بودن و توسعه‌ی آن توسط برنامه نویسان مجرب و کارکشته سراسر جهان است. کامپایلر GCC در برنامه‌های زیادی مورد استفاده قرار گرفته است؛ ازجمله: AVR Studio یا Arduino و… . این نیز خود نشان‌دهنده‌ی برتری این کامپایلر است.

برگرفته از سایت سیسوگ