Raspberry Pi ที่เสถียรที่สุด? ความแม่นยำของ NTP ดีขึ้น 81% ด้วยการจัดการความร้อน
(austinsnerdythings.com)- นำเสนอผลการทดลองที่ผสาน การตรึงคอร์ CPU และการทำให้อุณหภูมิคงที่ เพื่อลดความผันผวนของความถี่ใน เซิร์ฟเวอร์ NTP ที่ใช้ Raspberry Pi
- พบว่าการเปลี่ยนแปลงของอุณหภูมิ CPU ทำให้เกิด frequency drift ของคริสตัลออสซิลเลเตอร์ และแก้ไขด้วยการคงอุณหภูมิให้สม่ำเสมอ
- ใช้โปรเซส ‘time burner’ ที่อาศัยการควบคุมแบบ PID เพื่อรักษา CPU ไว้ที่ 54°C และทำได้ทั้ง ลดความผันผวนของความถี่ 81% และ ลดส่วนเบี่ยงเบนมาตรฐาน 77%
- ตรึง CPU 0 ให้ chronyd ใช้งานโดยเฉพาะ และใช้คอร์ที่เหลือสร้างภาระความร้อนคงที่ ทำให้ NTP offset ดีขึ้นจนมีค่าเฉลี่ย ราว 38ns
- ชี้ให้เห็นความเป็นไปได้ในการสร้าง เซิร์ฟเวอร์ timing ความแม่นยำสูงต้นทุนต่ำ สำหรับสภาพแวดล้อมที่ต้องการความเที่ยงตรงระดับสูงมาก เช่น การซิงก์เวลาแบบละเอียดหรืออุปกรณ์วิทยาศาสตร์
ปัญหา: ความไม่เสถียรของ timing จากการเปลี่ยนแปลงอุณหภูมิ
- ฟีเจอร์ การปรับความถี่แบบไดนามิก (DVFS) ของ Raspberry Pi มีข้อดีด้านประสิทธิภาพพลังงาน แต่ ไม่เหมาะกับการซิงก์เวลาที่ต้องการความแม่นยำสูง
- เมื่อความถี่สัญญาณนาฬิกาเปลี่ยนตามภาระ CPU ความเร็วของ tick ของ system clock ก็ผันผวนตามไปด้วย
- ความถี่ของคริสตัลออสซิลเลเตอร์ไวต่ออุณหภูมิ และเปลี่ยนแปลงได้ระดับหลาย ppm ตามความร้อนของ CPU
- เกิด frequency drift ตามความต่างของอุณหภูมิระหว่างกลางวันและกลางคืน
- จากการมอนิเตอร์ด้วย Grafana พบ frequency offset ราว ±1ppm ตามการเปลี่ยนแปลงของอุณหภูมิ CPU
- ค่าเฉลี่ย RMS offset อยู่ที่ระดับ 86ns จึงยังมีช่องให้ปรับปรุงได้
สิ่งที่ค้นพบ: ผลของการรักษาอุณหภูมิให้คงที่
- ยืนยันได้ว่าเมื่อรักษาอุณหภูมิ CPU ให้คงที่ จะช่วย เพิ่มเสถียรภาพของความถี่
- แนวทางแก้มี 2 ส่วน
- แยกคอร์ CPU – ให้ chronyd และ PPS interrupt ทำงานบน CPU 0 เท่านั้น
- ทำให้อุณหภูมิคงที่ – ให้คอร์ที่เหลือทำงานต่อเนื่องเพื่อรักษาอุณหภูมิให้สม่ำเสมอ
- เมื่อเปิดใช้งานระบบทำให้อุณหภูมิคงที่ในวันที่ 17 พฤศจิกายน 2025 เวลา 09:10 พบว่า การสั่นของความถี่ลดลงทันที
วิธีแก้ 1: ตรึงคอร์ CPU และตั้งลำดับความสำคัญแบบเรียลไทม์
- CPU 0: ใช้สำหรับ chronyd และ PPS interrupt โดยเฉพาะ
- CPU 1–3: ใช้สำหรับงานทั่วไปและรักษาภาระความร้อน
- จัดทำ สคริปต์ปรับแต่งอัตโนมัติ ให้รันตอนบูต
- ตรึงโหมดปรับความถี่ CPU เป็น performance
- ตรึง PPS IRQ(200) ไว้ที่ CPU 0
- ตั้ง chronyd ให้มีลำดับความสำคัญแบบเรียลไทม์ (SCHED_FIFO 50)
- เพิ่มลำดับความสำคัญของ โปรเซส ksoftirqd/0
- สามารถลงทะเบียนสคริปต์ผ่าน
/etc/rc.localหรือบริการ systemd ได้
วิธีแก้ 2: ทำให้อุณหภูมิคงที่ด้วยการควบคุมแบบ PID
- ใช้ ลูปควบคุมแบบ PID เพื่อรักษาอุณหภูมิ CPU ให้คงที่
- อุณหภูมิเป้าหมาย: 54°C
- ให้โปรเซส worker 3 ตัวบน CPU 1–3 สร้างภาระด้วยการคำนวณ MD5 hash
- ปรับ เวลาคำนวณและเวลารอ ตามค่า output ของ PID
- พารามิเตอร์ PID
- Kp=0.05, Ki=0.02, Kd=0.0
- เนื่องจากอุณหภูมิเปลี่ยนช้า จึงตั้งเทอมอนุพันธ์ (Kd) เป็น 0
- ผลลัพธ์คืออุณหภูมิ CPU คงที่อยู่ในช่วง ±0.2°C
ผลลัพธ์: เสถียรภาพของความถี่ดีขึ้น
- ความผันผวนของความถี่ลดลง 81%, ส่วนเบี่ยงเบนมาตรฐานลดลง 77%, RMS offset ลดลง 49%
- ค่าเฉลี่ย RMS offset: 85.44ns → 43.54ns
- มัธยฐาน RMS offset: 80.13ns → 37.93ns
- เมื่อรักษาอุณหภูมิ CPU ที่ 54°C ได้ เสถียรภาพของความถี่ในช่วง ±0.14ppm
- ยังคงเสถียรได้แม้อุณหภูมิห้องจะแปรผัน (18.9~22.2°C)
ขั้นตอนการตั้งค่า
- การเตรียมล่วงหน้า: ต้องสร้างเซิร์ฟเวอร์ NTP ที่อิง GPS PPS ก่อน
- ติดตั้งแพ็กเกจที่จำเป็น
linux-cpupower,python3,util-linux
- เขียน สคริปต์ปรับแต่งตอนบูต
/usr/local/bin/pps-optimize.shและลงทะเบียนกับ systemd - เขียน สคริปต์ควบคุมความร้อน
/usr/local/bin/time_burner.pyและลงทะเบียนเป็นบริการExecStart=/usr/bin/python3 /usr/local/bin/time_burner.py -t 54.0 -n 3
- คำสั่งตรวจสอบ
- ตรวจว่า CPU governor เป็น
performance - ตรวจการตรึง CPU และลำดับความสำคัญของ chronyd
- วัด RMS offset ด้วย
chronyc tracking(เช่น ระดับ 35ns)
- ตรวจว่า CPU governor เป็น
การมอนิเตอร์และการแก้ปัญหา
- มอนิเตอร์แบบเรียลไทม์:
watch -n 1 "chronyc tracking" - ตรวจสถานะบริการ:
sudo systemctl status time-burner.service - การจูน PID
- ถ้าอุณหภูมิสั่น ให้ลด Kp; ถ้าการคงที่ช้า ให้เพิ่ม Ki
- อุณหภูมิเป้าหมายปรับได้ในช่วง 50~60°C
- การใช้ CPU สูง (ประมาณ 90%) เป็นพฤติกรรมที่ตั้งใจไว้
ข้อแลกเปลี่ยน
- การใช้พลังงานเพิ่มขึ้น: ใช้ต่อเนื่อง 3–4W (ราว 15–25kWh ต่อปี)
- ความร้อนเพิ่มขึ้น: รักษาไว้ที่ 54°C ซึ่งยังอยู่ในช่วงปลอดภัย
- กินทรัพยากร CPU: ใช้ 3 คอร์จากทั้งหมด 4 คอร์
- เหมาะกับอุปกรณ์ที่ใช้ทำ NTP โดยเฉพาะ แต่ไม่เหมาะกับสภาพแวดล้อมที่รันหลายบริการ
งานที่นำไปใช้ได้
- การซิงก์เวลาอย่างแม่นยำ, อุปกรณ์วิทยาศาสตร์, งานวิจัยระบบกระจาย, การทดสอบเครือข่าย เป็นต้น
- แม้จะเกินความจำเป็นสำหรับงานทั่วไป แต่มีประโยชน์ในการสร้าง สภาพแวดล้อมทดลองความแม่นยำสูงต้นทุนต่ำ
แนวทางการปรับปรุงในอนาคต
- ใช้ adaptive PID tuning เพื่อรับมือการเปลี่ยนแปลงอุณหภูมิตามฤดูกาล
- ใช้ การควบคุมการระบายความร้อนด้วยฮาร์ดแวร์ (เช่น พัดลม PWM) เพื่อเพิ่มประสิทธิภาพพลังงาน
- หากใช้ OCXO (oven-controlled crystal oscillator) ก็อาจกำจัด thermal drift ได้
สรุป
- การผสานการตรึงคอร์ CPU กับการจัดการความร้อนด้วย PID ทำให้สร้าง เซิร์ฟเวอร์ NTP ความแม่นยำสูงมาก ได้
- เสถียรภาพของความถี่ดีขึ้น 81% และทำ RMS offset ได้ 38ns
- การทดลองนี้พิสูจน์ ความสัมพันธ์ระหว่างการจัดการความร้อนกับการจัดตารางแบบเรียลไทม์
- เป็นโครงการที่เน้น การสำรวจเชิงเทคนิคและคุณค่าด้านการเรียนรู้ มากกว่าการใช้งานจริง
1 ความคิดเห็น
ความคิดเห็นจาก Hacker News
เพราะ CPU0 มักรับ interrupt อื่น ๆ จำนวนมาก จึงไม่เหมาะกับงานที่ต้องการความแม่นยำด้าน timing สูง
มี system task จำนวนมากที่ย้ายออกจาก CPU0 ไม่ได้ ดังนั้นการใช้คอร์อื่นเป็น isolated core จะดีกว่ามาก
scheduler latency ของ isolated core ของเราเสถียรมาก โดยมีค่าต่ำสุด 1µs ค่าเฉลี่ย 5µs และค่าสูงสุดราว 59µs
บทความที่เกี่ยวข้อง: Spare Time – JILA
มวลความร้อนที่ทำจากขวดน้ำก็น่าสนใจเช่นกัน
ให้ผลคล้ายกับการใส่ หินอุ่น ไว้ในถุงนอน
LEA-M8T ของผมสร้าง time pulse ที่ 16Hz และตั้งค่า dpoll=-4 ใน chrony ทำให้เก็บได้ 256 ตัวอย่างในช่วง 16 วินาทีและช่วยเพิ่มเสถียรภาพ
ข้างโต๊ะผมยังมี BH3SAP GPSDO ด้วย โดย Claude ได้แก้เฟิร์มแวร์เพิ่ม flywheel mode ให้ยังสร้าง pulse ต่อได้แม้ไม่มี GPS PPS
และยังอัปเดตให้รองรับเอาต์พุต TSIP (โปรโตคอลของ Trimble) ด้วย เรื่องนี้จะเขียนถึงในโพสต์ถัดไป
เดี๋ยวจะมาตอบคอมเมนต์ต่าง ๆ เพิ่มด้วย และยินดีรับคำถามเสมอ
สงสัยว่า pulse 16Hz ช่วยได้มากแค่ไหนในทางปฏิบัติ และก็อยากรู้ด้วยว่าคุณส่งข้อมูลเข้า influxdb อย่างไร ฉันใช้ collectd แต่ข้อมูลมีไม่มากนัก
ถ้ามีแม้แต่เคสโลหะ ก็น่าจะให้ผลลัพธ์ที่เสถียรกว่าต่อการเปลี่ยนแปลงอุณหภูมิเป็นรอบ ๆ จากฮีตเตอร์หรือแอร์
เอกสารที่เกี่ยวข้อง: Raspberry Pi StackExchange – เปลี่ยนออสซิลเลเตอร์
วิธีนี้เพียงอย่างเดียวก็ลด drift ลงได้ 4-5 เท่า และจะยิ่งดีขึ้นถ้าทำร่วมกับเทคนิคอื่น
แต่ทักษะการบัดกรีของฉันยังไม่ดีพอ เลยไม่มั่นใจว่าจะเปลี่ยนเองได้
แม้แต่การตั้งค่า NTP server ธรรมดา ๆ ก็ยังมีเรื่องให้เรียนรู้อีกมาก
จึงระบายความร้อนแบบ passive cooling ได้ดีมากแม้ไม่มีพัดลม
ถ้าอุณหภูมิเปลี่ยนช้าลง clock drift ก็จะเปลี่ยนช้าลงตาม ทำให้ชดเชยได้ง่ายขึ้น
แต่ฮีตซิงก์ขนาดเล็กอาจกลับทำให้ไวต่ออุณหภูมิรอบข้างมากขึ้น
เพื่อบรรเทาการเปลี่ยนแปลงอุณหภูมิห้องอย่างรวดเร็ว เช่น ตอนเปิดหน้าต่างหรือหลังอาบน้ำที่มีความชื้นสูง และลดการที่ CPU เผาพลังงานโดยไม่จำเป็น
สุดท้ายแล้วเป้าหมายคือทำให้อุณหภูมิคงที่
คอร์อื่น ๆ ทำงานอยู่ใกล้อุณหภูมิสูงสุดอยู่แล้ว และมีการปรับความเร็วสัญญาณนาฬิกาอัตโนมัติตามอุณหภูมิ
การทำให้เย็นเกินไปอาจรบกวน กลไกควบคุมอุณหภูมิในตัว นี้ได้
และอาจเพิ่มทรานซิสเตอร์ที่ควบคุมผ่าน GPIO เพื่อรักษาอุณหภูมิด้วย การควบคุมแบบ PID
เพราะใช้คริสตัลที่ตัดมาให้มี temperature coefficient ใกล้ 0 จึงมีความเสถียรสูง
อุปกรณ์สมัยใหม่ก็ยังใช้โครงสร้างแบบนี้อยู่ และมักใช้เวลาราว 5 นาทีจึงจะเสถียรเต็มที่
มันช่วยลดผลจากอุณหภูมิรอบข้างได้ แต่ท้ายที่สุด การใส่มันไว้ใน ห้องควบคุมอุณหภูมิ ก็ยังเป็นวิธีที่แน่นอนที่สุด
ตัวอย่างเช่น ใช้บอร์ด STM32 ต่ออีเธอร์เน็ตแล้วทำเป็น NTP server ก็น่าจะเสถียรกว่า
มันสามารถป้อนสัญญาณ NTP ให้ Pi ได้ และ STM32 ก็ได้เช่นกัน แต่โดยพื้นฐานแล้วไม่มีฟังก์ชันอีเธอร์เน็ตมาให้
RTLinux ยังมีความสามารถในการซิงก์ scheduler กับสถานะของขาภายนอกได้ด้วย
แต่เมื่อมีโปรเซสเซอร์หลายตัว ก็จะเกิดปัญหา metastability
Pi ไม่ได้ให้การรับประกันด้านเรียลไทม์แบบเดียวกับ FPGA (Zynq)
แต่เพราะมันกินไฟต่ำ จึงสมเหตุสมผลกว่าที่จะยอมสิ้นเปลืองพลังงานเล็กน้อย แทนการใช้ระบบระบายความร้อนที่ซับซ้อน
วิธีตรวจจับ jitter ด้วยสัญญาณ PPS สองเส้นเป็นเทคนิคเก่ามากแล้ว และ การเรียนรู้ tempco ก็มีมาหลายสิบปี
สิ่งที่ขาดไปคือการตรวจสอบว่า tempco ที่เรียนรู้มาแล้วนั้นแม่นยำจริงแค่ไหน