Raining Season

Optimizing C and C++ code for Embedded System (Thai language)


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;
                                     :
                                     :
                              }
     
     
     }


Share this page :

Custom Search