۱۳۸۸ شهریور ۱۸, چهارشنبه

Optimizer در WinAVR

بهینه ساز کامپایلر winavr

 

بهینه ساز کامپایلر چیست؟

بهینه ساز یک قسمت از کامپایلر است که کدهای زائد را حذف می کند.در حال حاضر winavr قوی ترین بهینه ساز را بین کامپایلرهای avr دارد.البته این کار گاهی در عملکرد برنامه اختلال ایجاد می کند که می توان با دستور Volatile که بعدا در مورد آن توضیح می دهیم از این اختلال جلوگیری کرد.

بهینه ساز ها با تنظیماتی در کامپایلر قابل تنظیم هستند و می توان سطوح مختلفی را برای کنترل نوع رفتار آنها انتخاب کرد. کامپایلر winavr چهار سطح بهینه سازی دارد.

O0

غیر فعال کردن بهینه ساز.

O1

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

O2

بهینه سازی بیشتر از حالت قبل با اولویت افزایش سرعت.

O3

همانند O2 ولی تمام توابع به صورت inline کامپایل می شوند. بیشترین سرعت اجرای برنامه.

Os

بهینه سازی برای کم کردن ظرفیت. کامل ترین سطح بهینه سازی کد.

 

 

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

 

 

Optimize level

Program (byte)

Data (byte)

O0

7936

78

O1

3600

70

O2

3980

70

O3

7184

70

Os

3898

70

 

 

اشتباه در بهینه سازی کد

Volatile ، این کلمه کلیدی بسیار کم در برنامه نویسی استفاده می شود.

آیا تا به حال در برنامه های C/C++ این تجربه را کرده اید که ، کدی که نوشته اید ، تا زمانی که optimize (بهینه ساز هوشمندی که کامپایلر ها برای بالا بردن سرعت اجرا و کم حجم کردن برنامه از آن بهره می گیرند) خاموش است برنامه بخوبی کار می کند، ولی با فعال کردن این قابلیت در کامپیلر برنامه قاطی می کند و عملکرد آن مختل می شود.

 

این اتفاقات به دلیل این است که شما تا به حال از کلمه Volatile در برنامه تان استفاده نکرده اید. Volatile یک کلمه توصیفی برای تعریف یک متغییر است. این کلمه به کامپایلر می گوید که این متغییر ممکن است هر زمانی تغییر کند( مثلا توسط در اینتراپت) پس کامپایلر هنگام بهینه سازی برنامه ، از حذف این متغییر و خطوطی که این متغییر در آنها استفاده شده صرف نظر می کند.

 

قبل از توضیحات بیشتر تعریف متغییر از نوع  Volatile را بررسی می کنیم.

برای تعریف یک متغییر به صورت Volatile باید این کلمه را قبل یا بعد از نوع متغییر بیاوریم:

volatile int foo;

یا

int volatile foo;

 

اشاره گرهای Volatile بسیار پر کاربرد هستند، چون بیشتر مواقع اشاره گرها قربانی بهینه ساز کامپایلر می شوند.

pointers to volatile variables:

volatile int * foo;

int volatile * foo;

Volatile pointers to non-volatile variables:

int * volatile foo;

volatile pointer to a volatile variable:

int volatile * volatile foo;

 

کجا از volatile استفاده کنیم؟

در برنامه نویسی PC سه جا باید از این کلمه استفاده کنیم (اما کامپایلر های امروزی که برای PC هستند آنقدر تکامل یافته اند که چنین اشتباهی نمی کنند) ولی در برنامه نویسی میکرو تمام متغییر هایی عمومی که بین برنامه جاری و سرویس وقفه مشترک هستند باید volatile تعریف شوند تا مشکلی پیش نیاید.

 

 

 

یک مثال :

در این بر نامه که یک چشمک زن ساده است ، می بینید که اگر متغییر عمومی tick به صورت volatile تعریف نشود برنامه کار نمی کند.


حالت اول بدون volatile که کار نمی کند.
#include

#include

int tick = 0; int main(){


DDRC = 0xff; //define portc as out put.

PORTA = 0xff; //enable internal pullups.

TCCR0 |= 5; //enable and run timer 0.

TIMSK |= 1< tick ="=" portc =" PORTC"> if(PORTC == 0) PORTC = 1; tick = 0; } }


}


ISR(TIMER0_OVF_vect)

{

tick = 1;

}

حالت دوم با volatile که کار می کند.

#include

#include


volatile‏ int tick = 0; int main(){ DDRC = 0xff; //define portc as out put.


PORTA = 0xff; //enable internal pullups.

TCCR0 |= 5; //enable and run timer 0.

TIMSK |= 1< tick ="=" portc =" PORTC"> if(PORTC == 0) PORTC = 1; tick = 0; } }


}


ISR(TIMER0_OVF_vect)

{

tick = 1;

}


این برنامه را به همراه فایل پروتئوس از اینجا دانلود کنید.







هیچ نظری موجود نیست: