คำตอบของ @ vicatcu นั้นค่อนข้างครอบคลุม สิ่งหนึ่งที่ควรทราบเพิ่มเติมคือ CPU อาจทำงานเป็นสถานะรอ (รอบ CPU ค้าง) เมื่อเข้าถึง I / O รวมถึงโปรแกรมและหน่วยความจำข้อมูล
ตัวอย่างเช่นเราใช้ TI F28335 DSP พื้นที่บางส่วนของ RAM เป็นสถานะ 0- รอสำหรับโปรแกรมและหน่วยความจำข้อมูลดังนั้นเมื่อคุณรันโค้ดใน RAM มันจะทำงานที่ 1 รอบต่อการเรียนการสอน (ยกเว้นสำหรับคำสั่งที่ใช้เวลามากกว่า 1 รอบ) เมื่อคุณเรียกใช้รหัสจากหน่วยความจำ FLASH (EEPROM ในตัวไม่มากก็น้อย) แต่มันไม่สามารถทำงานที่ 150MHz เต็มและช้าลงหลายครั้ง
เกี่ยวกับโค้ดขัดจังหวะความเร็วสูงคุณต้องเรียนรู้หลายสิ่งหลายอย่าง
ก่อนอื่นให้ทำความคุ้นเคยกับคอมไพเลอร์ของคุณ หากคอมไพเลอร์ทำงานได้ดีก็ไม่น่าจะช้ากว่าชุดประกอบที่เขียนด้วยมือสำหรับสิ่งส่วนใหญ่ (โดยที่ "ช้ากว่ามาก": ปัจจัย 2 จะโอเคโดยฉันปัจจัย 10 ไม่สามารถยอมรับได้) คุณต้องเรียนรู้วิธี (และเมื่อ) ใช้แฟล็กการเพิ่มประสิทธิภาพคอมไพเลอร์และทุกครั้งที่คุณควรมอง ที่เอาต์พุตของคอมไพเลอร์เพื่อดูว่ามันทำอย่างไร
บางสิ่งอื่น ๆ ที่คุณสามารถให้คอมไพเลอร์ทำเพื่อเร่งโค้ด:
ใช้ฟังก์ชั่นแบบอินไลน์ (จำไม่ได้ว่า C รองรับสิ่งนี้หรือถ้าเป็นเพียง C ++ - ism) ทั้งสำหรับฟังก์ชั่นขนาดเล็กและสำหรับฟังก์ชั่นที่จะถูกดำเนินการเพียงครั้งเดียวหรือสองครั้ง ข้อเสียคือฟังก์ชั่นอินไลน์ยากต่อการดีบักโดยเฉพาะอย่างยิ่งหากการปรับแต่งคอมไพเลอร์เปิดอยู่ แต่พวกเขาจะช่วยคุณประหยัดลำดับการโทร / ส่งคืนโดยไม่จำเป็นโดยเฉพาะอย่างยิ่งหากสิ่งที่เป็นนามธรรม "ฟังก์ชั่น" สำหรับวัตถุประสงค์ในการออกแบบแนวคิดมากกว่าการใช้รหัส
ดูคู่มือคอมไพเลอร์ของคุณเพื่อดูว่ามันมีฟังก์ชั่นที่แท้จริงหรือไม่ - นี่คือฟังก์ชั่นบิวอินในตัวคอมไพเลอร์ที่แมปกับคำสั่งแอสเซมบลีของโปรเซสเซอร์โดยตรง โปรเซสเซอร์บางตัวมีคำแนะนำการประกอบที่ทำสิ่งที่มีประโยชน์เช่น min / max / bit reverse และคุณสามารถประหยัดเวลาได้
หากคุณกำลังคำนวณตัวเลขให้แน่ใจว่าคุณไม่ได้เรียกฟังก์ชั่นคณิตศาสตร์ห้องสมุดโดยไม่จำเป็น เรามีกรณีหนึ่งที่รหัสนั้นคล้ายy = (y+1) % 4
กับตัวนับที่มีระยะเวลา 4 คาดว่าคอมไพเลอร์จะใช้โมดูโล 4 เป็นบิต - และ มันเรียกว่าห้องสมุดคณิตศาสตร์แทน ดังนั้นเราจึงแทนที่ด้วยy = (y+1) & 3
เพื่อทำสิ่งที่เราต้องการ
ทำความคุ้นเคยกับหน้าบิต twiddling แฮ็ก ฉันรับประกันว่าคุณจะใช้อย่างน้อยหนึ่งอย่างต่อไปนี้
คุณควรใช้อุปกรณ์ต่อพ่วงตัวจับเวลาของ CPU เพื่อวัดเวลาประมวลผลโค้ดส่วนใหญ่มีตัวจับเวลา / ตัวนับที่สามารถตั้งค่าให้ทำงานที่ความถี่สัญญาณนาฬิกาของ CPU จับสำเนาตัวนับที่จุดเริ่มต้นและจุดสิ้นสุดของรหัสที่สำคัญของคุณและคุณสามารถดูได้ว่าต้องใช้เวลานานเท่าใด หากคุณไม่สามารถทำเช่นนั้นได้อีกทางเลือกหนึ่งคือลดขาเอาต์พุตที่จุดเริ่มต้นของรหัสของคุณและเพิ่มมันที่ส่วนท้ายและดูผลลัพธ์นี้บนออสซิลโลสโคปเพื่อกำหนดเวลาดำเนินการ มีวิธีการแลกเปลี่ยนในแต่ละวิธี: ตัวจับเวลาภายใน / ตัวนับมีความยืดหยุ่นมากขึ้น (คุณสามารถใช้เวลาหลายสิ่ง) แต่ยากที่จะรับข้อมูลออกในขณะที่การตั้งค่า / การล้างขาออกจะมองเห็นได้ทันทีในขอบเขตและคุณสามารถบันทึกสถิติได้ เป็นการยากที่จะแยกแยะเหตุการณ์ต่าง ๆ
ในที่สุดก็มีเป็นทักษะที่สำคัญมากที่มาพร้อมกับประสบการณ์ - ทั้งทั่วไปและกับชุดประมวลผล / คอมไพเลอร์ที่เฉพาะเจาะจง: รู้เมื่อและเมื่อไม่เพิ่มประสิทธิภาพ โดยทั่วไปคำตอบคือไม่ปรับให้เหมาะสม การเสนอราคา Donald Knuth ได้รับการโพสต์บ่อยครั้งใน StackOverflow (มักเป็นเพียงส่วนสุดท้าย):
เราควรลืมเกี่ยวกับประสิทธิภาพเล็กน้อยพูดถึง 97% ของเวลา: การเพิ่มประสิทธิภาพก่อนวัยอันควรเป็นรากฐานของความชั่วร้ายทั้งหมด
แต่คุณอยู่ในสถานการณ์ที่คุณรู้ว่าคุณต้องทำการเพิ่มประสิทธิภาพบางอย่างดังนั้นถึงเวลากัดกระสุนและปรับให้เหมาะสม (หรือรับโปรเซสเซอร์ที่เร็วกว่าหรือทั้งสองอย่าง) อย่าไม่เขียน ISR ของคุณทั้งหมดในการชุมนุม นั่นเกือบจะเป็นหายนะที่รับประกันได้ถ้าคุณทำภายในไม่กี่เดือนหรือหลายสัปดาห์คุณจะลืมบางส่วนของสิ่งที่คุณทำและเพราะอะไรและรหัสมีแนวโน้มที่จะเปราะบางและยากที่จะเปลี่ยนแปลง มีแนวโน้มที่จะมีบางส่วนของรหัสของคุณซึ่งเป็นตัวเลือกที่ดีสำหรับการประกอบ
สัญญาณที่ว่าบางส่วนของรหัสของคุณเหมาะสำหรับการประกอบรหัส:
- ฟังก์ชันที่มีรูทีนขนาดเล็กที่มีการกำหนดไว้อย่างดีซึ่งไม่น่าจะมีการเปลี่ยนแปลง
- ฟังก์ชั่นที่สามารถใช้คำสั่งประกอบเฉพาะ (ขั้นต่ำ / สูงสุด / ขวากะ / ฯลฯ )
- ฟังก์ชั่นที่เรียกหลายครั้ง (ทำให้คุณเพิ่มทวีคูณ: ถ้าคุณบันทึก 0.5usec ในการโทรแต่ละครั้งและได้รับการเรียก 10 ครั้งคุณจะประหยัด 5 usec ซึ่งมีความสำคัญในกรณีของคุณ)
เรียนรู้ฟังก์ชั่นการเรียกประชุมของคอมไพเลอร์ของคุณ (เช่นที่ทำให้ข้อโต้แย้งในการลงทะเบียนและการลงทะเบียนมันบันทึก / เรียกคืน) เพื่อให้คุณสามารถเขียนรูทีนแอสเซมบลีแบบ C-callable
ในโครงการปัจจุบันของฉันเรามี codebase ขนาดใหญ่ที่มีรหัสสำคัญที่ต้องทำงานในการขัดจังหวะ 10kHz (คุ้นเคยกับ 100usec - sound คุ้นหู?) และมีฟังก์ชั่นมากมายที่เขียนไว้ในชุดประกอบ สิ่งที่เป็นคือสิ่งต่าง ๆ เช่นการคำนวณซีอาร์ซีคิวซอฟต์แวร์ ADC กำไร / ชดเชยค่าชดเชย
โชคดี!