Optimizing C and C++ code for Embedded System (Thai language)
Fri, 06/27/2014 - 13:51 — ataya_p
Written
by
:
Ataya P
Date
: 27 May 2007
Language
: Thai
ก่อนอื่นต้องของสวัสดีพี่น้องทุกท่าน
บทความนี้ที่ต้องเขียนเป็นภาษาไทยก็เพราะว่าเป็นบทความที่แปลมาจากภาษาอังกฤษอีกทีก็เลยไม่รู้ว่าจะเขียนซ้ำเป็นภาษาอังกฤษไปทำไม
สำหรับท่านที่ทำงานด้าน Embeded System ไม่ว่าจะเป็นการใช้งาน
Microcontroller หรือเขียนโปรแกรมติดต่อกับระบบก็ตาม บางท่านอาจจะสงสัยว่า
"ทำไมมันช้าแบบนี้นะ" หรือ "โปรแกรมตูทำไมกินแรมไปซะขนาดนี้ฟะเนี่ย"
ลองอ่านบทความนี้ดูแล้วท่านอาจจะถึงบางอ้อบ้างก็ได้นะขอรับ
(*_*)/"
-> Adjust
structure size to power of two
เวลาที่ compiler ทำ indexing
array
ของข้อมูลที่เราเขียนเป็น structure นั้น ปกติcompiler
จะต้องใช้พื้นที่เท่าตัวของขนาดของ structure (size of
structure)แต่หากเราเขียนให้ structure ให้มีขนาดเท่ากับสองยกกำลัง n
(power
of two : 2^0=1 ,2^1=2 ,2^2=4
,2^3=8,.....) แล้วละก็
การทำ indexing ก็จะเปลี่ยนเป็นการใช้ shift operation
แทนซึ่งจะเร็วกว่าปกติมากทีเดียว
->
Place case labels in narrow range
ถ้าใน switch case
label มีการกำหนดโดยให้มีระยะห่างระหว่าง case น้อยๆ เช่น
switch(input)
{
case 1: break;
case 2:.break;
case 3
: break;
}
เวลาที่ compile คอมไพล์เลอร์ก็จะทำการ
generate
ให้แบบ lookup table และจะกระโดดไปทำงานตาม case นั้นๆ
หากเรากำหนดให้ case label มีความห่างกันมากๆแล้วละก็ (เช่น 1,10,20,100)
โดยทั่วไป compiler จะทำการ
generate ให้แบบ if-case ซึ่งจะเสียเวลาโปรเซสมากกว่าแบบ lookup table
->
Place frequent case labels first
หากในกรณีที่ case lable มีค่าห่างกันมาก
ๆ compiler
จะทำการเปรียบเทียบแบบ if-else
ซึ่งจะทำงานได้ช้าเพราะต้องทำการเปรียบเทียบทีละcase
จึงเป็นการดีกว่าที่จะเอา case ที่ต้องถูกใช้งานบ่อยๆมาไว้ก่อน
จะได้ไม่ต้องเสียเวลา check case หลังๆ ที่ไม่ค่อยจะถูกใช้งาน
(และนี่คือคือเหตุผลว่าทำไมส่วนใหญ่ จึงมักจะเอา case
ที่ใช้จัดการกับเหตุการณ์ error ไว้หลังสุด
เนื่องจากมันมักจะไม่ค่อยเกิดขึ้นเท่าไรนั่นเอง)
switch(msg){
case FREQ1
: break;
if(msg ===FREQ1){ }else
case
FREQ2
: break;
====>
if(msg
== FREQ2) { }else
:
:
:
:
case ERROR
: break;
if(msg === ERROR){}
}
-> Break big
switch statements into nested switches
ในบางกรณี เทคนิคก่อนหน้านี้อาจไม่ได้ผล
เนื่องจาก
compiler อาจ generate ออกมาแบบ if-else แล้วก็ไม่เรียงลำดับตาม C code
ของเรา ในกรณีเช่นนี้ ควรใช้วิธี nested switch
ซึ่งจะเป็นการบังคับให้โค้ด Assembly ที่ generate ออกมาเรียงลำดับกัน
switch(msg){
case FREQ1 : break;
case FREQ2 : break;
:
:
default : switch(msg){
case INFREQ1 : break;
case INFREQ2 :
break;
:
:
}
}