1 Punkte von GN⁺ 2025-11-27 | 1 Kommentare | Auf WhatsApp teilen
  • Vorstellung der Ergebnisse eines Experiments, das zur Reduzierung von Frequenzschwankungen eines Raspberry-Pi-basierten NTP-Servers CPU-Core-Pinning und thermische Stabilisierung kombiniert
  • Es wurde beobachtet, dass Änderungen der CPU-Temperatur Frequenzdrift des Quarzoszillators verursachen; durch das Halten einer konstanten Temperatur wurde dies stabilisiert
  • Ein PID-gesteuerter „time burner“-Prozess hält die CPU bei 54 °C und erreicht 81 % weniger Frequenzschwankung sowie 77 % geringere Standardabweichung
  • CPU 0 wird exklusiv für chronyd reserviert, während die übrigen Kerne die thermische Last aufrechterhalten, wodurch der NTP-Offset auf durchschnittlich 38 ns verbessert wird
  • Zeigt die Möglichkeit, in Umgebungen mit Bedarf an extremer Genauigkeit – etwa präziser Zeitsynchronisation oder wissenschaftlichen Geräten – einen kostengünstigen hochpräzisen Timing-Server zu realisieren

Problem: Instabiles Timing durch Temperaturänderungen

  • Die dynamische Frequenzskalierung (DVFS) des Raspberry Pi ist zwar vorteilhaft für die Energieeffizienz, aber nachteilig für präzise Zeitsynchronisation
    • Wenn sich die Taktfrequenz mit der CPU-Last ändert, schwankt auch die Tick-Rate der Systemuhr
  • Die Frequenz des Quarzoszillators ist temperaturabhängig und ändert sich durch die CPU-Abwärme im Bereich einiger ppm
    • Durch Temperaturänderungen zwischen Tag und Nacht entsteht Frequenzdrift
  • Das Grafana-Monitoring zeigte in Abhängigkeit von der CPU-Temperatur einen Frequenzoffset von etwa ±1 ppm
    • Der durchschnittliche RMS-Offset lag bei etwa 86 ns, es bestand also Verbesserungspotenzial

Erkenntnis: Der Effekt einer konstanten Temperatur

  • Wenn die CPU-Temperatur konstant gehalten wird, lässt sich die Frequenzstabilität verbessern
  • Die Lösung besteht aus zwei Teilen
    1. CPU-Core-Isolierung – chronyd und PPS-Interrupts werden nur CPU 0 zugewiesen
    2. Thermische Stabilisierung – die übrigen Kerne laufen kontinuierlich, um eine konstante Temperatur zu halten
  • Als das thermische Stabilisierungssystem am 17. November 2025 um 09:10 aktiviert wurde, gingen die Frequenzschwingungen sofort zurück

Lösung 1: CPU-Core-Pinning und Echtzeit-Priorität

  • CPU 0: exklusiv für chronyd und PPS-Interrupts
  • CPU 1–3: allgemeine Aufgaben und Aufrechterhaltung der thermischen Last
  • Einrichtung eines Optimierungsskripts, das beim Booten automatisch ausgeführt wird
    • CPU-Frequenzmodus fest auf performance setzen
    • PPS IRQ(200) auf CPU 0 festlegen
    • chronyd mit Echtzeit-Priorität (SCHED_FIFO 50) ausführen
    • Priorität des Prozesses ksoftirqd/0 erhöhen
  • Das Skript kann in /etc/rc.local oder als systemd-Service registriert werden

Lösung 2: Thermische Stabilisierung per PID-Regelung

  • Um die CPU-Temperatur konstant zu halten, wird eine PID-Regelschleife verwendet
    • Zieltemperatur: 54 °C
    • Drei Worker-Prozesse auf CPU 1–3 erzeugen Last durch MD5-Hash-Berechnungen
    • Je nach PID-Ausgabewert werden Rechenzeit und Wartezeit angepasst
  • PID-Parameter
    • Kp=0.05, Ki=0.02, Kd=0.0
    • Da sich die Temperatur langsam ändert, ist der Differentialanteil (Kd) 0
  • Dadurch bleibt die CPU-Temperatur stabil innerhalb von ±0,2 °C

Ergebnis: Verbesserte Frequenzstabilität

  • 81 % weniger Frequenzschwankung, 77 % geringere Standardabweichung, 49 % weniger RMS-Offset
  • Durchschnittlicher RMS-Offset: 85,44 ns → 43,54 ns
  • Medianer RMS-Offset: 80,13 ns → 37,93 ns
  • Bei auf 54 °C gehaltener CPU-Temperatur wurde eine Frequenzstabilität im Bereich von ±0,14 ppm erreicht
  • Die Stabilität blieb trotz Schwankungen der Raumtemperatur (18,9–22,2 °C) erhalten

Einrichtungsverfahren

  • Vorbereitung: Ein GPS-PPS-basierter NTP-Server muss eingerichtet sein
  • Erforderliche Pakete installieren
    • linux-cpupower, python3, util-linux
  • Boot-Optimierungsskript /usr/local/bin/pps-optimize.sh erstellen und in systemd registrieren
  • Skript zur Wärmeregelung /usr/local/bin/time_burner.py erstellen und als Service registrieren
    • ExecStart=/usr/bin/python3 /usr/local/bin/time_burner.py -t 54.0 -n 3
  • Prüfbefehle
    • CPU-Governor: performance prüfen
    • CPU-Bindung und Priorität von chronyd prüfen
    • Mit chronyc tracking den RMS-Offset messen (z. B. etwa 35 ns)

Monitoring und Fehlerbehebung

  • Echtzeit-Monitoring: watch -n 1 "chronyc tracking"
  • Service-Status prüfen: sudo systemctl status time-burner.service
  • PID-Tuning
    • Bei Temperaturschwingungen Kp reduzieren, bei verzögerter Stabilisierung Ki erhöhen
    • Die Zieltemperatur kann im Bereich von 50–60 °C angepasst werden
  • Eine hohe CPU-Auslastung (etwa 90 %) ist beabsichtigt

Trade-offs

  • Höherer Stromverbrauch: kontinuierlich 3–4 W (etwa 15–25 kWh pro Jahr)
  • Mehr Wärmeentwicklung: 54 °C konstant, innerhalb des sicheren Bereichs
  • Belegung von CPU-Ressourcen: 3 von 4 Kernen werden genutzt
    • Für dedizierte NTP-Geräte geeignet, für Umgebungen mit mehreren Diensten ungeeignet

Mögliche Einsatzbereiche

  • Präzise Zeitsynchronisation, wissenschaftliche Geräte, Forschung an verteilten Systemen, Netzwerktests usw.
  • Für den allgemeinen Einsatz übertrieben, aber nützlich zum Aufbau kostengünstiger hochpräziser Experimentierumgebungen

Künftige Verbesserungen

  • Reaktion auf saisonale Temperaturschwankungen durch adaptives PID-Tuning
  • Verbesserung der Energieeffizienz durch hardwarebasierte Kühlregelung (z. B. PWM-Lüfter)
  • Mit einem OCXO (ofenstabilisierter Quarzoszillator) ließe sich thermische Drift eliminieren

Fazit

  • Durch die Kombination aus CPU-Core-Pinning und PID-gesteuertem Wärmemanagement wurde ein ultrapräziser NTP-Server realisiert
  • 81 % bessere Frequenzstabilität, RMS-Offset von 38 ns erreicht
  • Das Experiment belegt den Zusammenhang zwischen Wärmemanagement und Echtzeit-Scheduling
  • Es handelt sich eher um ein Projekt mit Fokus auf technischer Erkundung und Lernwert als auf praktische Einsetzbarkeit

1 Kommentare

 
GN⁺ 2025-11-27
Hacker-News-Kommentare
  • Wenn man CPU0 meidet und in der Kernel-Kommandozeile idle=poll setzt, kann man eine bessere Präzision erreichen
    Auf CPU0 landen andere Interrupts, daher ist sie für Aufgaben mit hoher Timing-Präzision ungeeignet
    • Sehe ich genauso. In unserer Debian-basierten OS-Distribution machen wir ähnliche Optimierungen wie das Deaktivieren von Frequency Scaling und das Pinning von Kernen
      Auf CPU0 laufen viele Systemaufgaben, die man nicht verschieben kann, daher ist es viel besser, einen anderen Kern als isolierte Insel (isolated core) zu verwenden
      Die Scheduler-Latenz unseres isolierten Kerns ist sehr stabil: mindestens 1µs, im Durchschnitt 5µs und maximal etwa 59µs
    • Guter Tipp. Ich werde das heute später selbst ausprobieren
  • Beim WWVB-Sender wird die Ausrüstung mit Hunderten von Wasserflaschen thermisch isoliert, um Temperaturschwankungen zu verhindern
    Zugehöriger Artikel: Spare Time – JILA
    • Diese Seite ist es wert, separat geteilt zu werden. Besonders beeindruckend ist, dass dort vier Atomuhren betrieben werden und die USV aus zwei Autobatterien und zwei Scheinwerfern besteht
      Auch die thermische Masse aus Wasserflaschen ist interessant
    • Ich nutze eine ähnliche Methode. Ich lagere Wasser unter dem Schreibtisch in einem isolierten Lagerraum, damit es über Nacht nicht gefriert
      Das ist ähnlich wie ein warmer Stein im Schlafsack
  • Ich bin Austin (austinsnerdythings.com). Ich habe den Beitrag gestern Nacht veröffentlicht und war überrascht, als ich aufwachte und er auf Platz 1 bei HN stand
    Mein LEA-M8T erzeugt einen Time Pulse mit 16Hz, und in der chrony-Konfiguration habe ich dpoll=-4 gesetzt. Durch das Sammeln von 256 Samples im Abstand von 16 Sekunden hat sich die Stabilität verbessert
    Neben meinem Schreibtisch steht auch ein BH3SAP GPSDO. Claude hat die Firmware so geändert, dass ein Flywheel-Modus hinzugefügt wurde, der auch ohne GPS PPS weiter Pulse erzeugt
    Außerdem wurde Unterstützung für die TSIP-Ausgabe (Trimble-Protokoll) ergänzt. Darauf werde ich in einem nächsten Beitrag eingehen
    Ich werde auch bald auf die Kommentare antworten, und Fragen sind jederzeit willkommen
    • Danke für den guten Beitrag. Ich habe ein ähnliches Setup, daher ist das sehr hilfreich für mich
      Mich würde interessieren, wie viel Unterschied der 16Hz-Puls tatsächlich macht. Und ich würde gern wissen, wie du die Daten in influxdb bekommst. Ich nutze collectd, aber dazu gibt es nicht viele Informationen
    • Tolles Projekt. Mich würde interessieren, ob du den Raspberry Pi in ein Gehäuse eingebaut hast
      Selbst ein Metallgehäuse könnte stabilere Ergebnisse gegenüber zyklischen Temperaturschwankungen durch Heizung oder Klimaanlage liefern
  • Wenn man den günstigen Pi-Oszillatorkristall durch einen TCXO ersetzt, bekommt man eine deutlich stabilere Frequenz
    Zugehörige Dokumentation: Raspberry Pi StackExchange – Oszillator austauschen
    Allein damit lässt sich der Drift um das 4- bis 5-Fache verringern. In Kombination mit anderen Techniken ist es noch besser
    • Ich habe diesen Beitrag mehrfach gelesen. Es gibt auch ein audiophiles HAT für den Pi4 mit OCXO zu kaufen
      Aber meine Lötkenntnisse reichen nicht aus, um den Austausch selbst vorzunehmen
    • Der TCXO-Preis ist überraschend niedrig. Einige Produkte von Abracon lagen unter 2 Dollar
  • Das ist ein OCXO im SBC-Maßstab. Ich frage mich, ob ein größerer Kühlkörper oder zusätzliche thermische Masse um den Oszillator herum helfen würde
    Selbst beim simplen Einrichten eines NTP-Servers kann man viel lernen
    • Ich empfehle das Flirc-Metallgehäuse. Die CPU liegt direkt am Gehäusekörper an und bildet so eine große thermische Masse
      Damit ist ausgezeichnete passive Kühlung ohne Lüfter möglich
    • Ich denke ähnlich. Es wäre wohl gut, einen Metallblock auf CPU und Oszillator zu legen, um die thermische Trägheit zu erhöhen
      Wenn sich die Temperatur langsam ändert, ändert sich auch der Clock-Drift langsamer, was die Korrektur erleichtert
      Ein kleiner Kühlkörper könnte allerdings im Gegenteil empfindlicher auf Änderungen der Umgebungstemperatur reagieren
    • Ich denke auch darüber nach, dem Pi-Gehäuse Isoliermaterial hinzuzufügen
      Das könnte schnelle Änderungen der Raumtemperatur abmildern, etwa durch geöffnete Fenster oder Feuchtigkeit nach dem Duschen, und verhindern, dass die CPU unnötig Wärme verpulvert
      Letztlich geht es darum, die Temperatur konstant zu halten
    • Zu viel Wärmeabgabe könnte allerdings sogar kontraproduktiv sein
      Andere Kerne arbeiten bereits nahe an ihrer Maximaltemperatur und passen ihre Taktgeschwindigkeit temperaturabhängig automatisch an
      Übermäßige Kühlung könnte diesen selbstständigen Temperaturregelungsmechanismus stören
  • Man kann auch einen Widerstand und Schaumstoffisolierung am Kristall anbringen, um ihn direkt zu beheizen
    Mit einem per GPIO steuerbaren Transistor ließe sich die Temperatur auch per PID-Regelung konstant halten
    • Diese Methode wird schon seit fast 100 Jahren verwendet. In den 1950er Jahren wurden Kristallöfen in kleinen Metallkästen auf etwa 75°C gehalten
      Dabei kamen Kristalle zum Einsatz, die so geschnitten waren, dass ihr Temperaturkoeffizient nahe 0 lag, was für Stabilität sorgte
      Auch moderne Geräte verwenden noch immer diese Struktur, und bis zur vollständigen Stabilisierung dauert es ungefähr 5 Minuten
    • Ich habe früher auch mit dem Experiment gespielt, den Pi auf Verpackungsschaum zu stellen
      Das verringerte die Auswirkungen von Änderungen der Umgebungstemperatur, aber letztlich ist ein temperaturgeregelter Schrank die sicherste Lösung
  • Statt die CPU absichtlich zu verheizen, um die Temperatur zu halten, wäre es vielleicht besser, einen Mikrocontroller und einen Präzisionsoszillator zu verwenden
    Zum Beispiel könnte man ein STM32-Board mit Ethernet anschließen und als NTP-Server verwenden, was stabiler sein dürfte
    • Ich habe so etwas auch. Es ist ein BH3SAP GPSDO, den ich für 70 Dollar bei eBay gekauft habe, und mit modifizierter Firmware unterstützt er den Flywheel-Modus
      Er kann NTP-Signale an den Pi liefern, und auch STM32 wäre möglich, aber standardmäßig gibt es keine Ethernet-Funktion
    • Im Allgemeinen ist NTP ein zeitkritischer Prozess, daher ist ein MCU viel stabiler als ein SoC
      RTLinux hat sogar Funktionen, um den Scheduler mit dem Zustand externer Pins zu synchronisieren
      Wenn jedoch viele Prozessoren beteiligt sind, treten Metastabilitätsprobleme auf
      Ein Pi bietet keine Echtzeitgarantien wie ein FPGA (Zynq)
  • Auf die Idee, die SoC-Temperatur durch absichtliche Last konstant zu halten, wäre ich nicht gekommen
    Aber weil der Stromverbrauch niedrig ist, ist es vernünftig, das Problem eher mit etwas Energieverschwendung als mit einem komplexen Kühlsystem zu lösen
  • 2022 gab es dazu eine Arbeit: USENIX NSDI22 – Najafi
    • Interessante Arbeit. Sie löst das Problem eleganter, indem sie die Temperaturreaktionskurve modelliert, statt einfach die CPU zu verheizen
    • Allerdings beobachtet die Arbeit im Grunde nur die Vielfalt der Temperatursensoren in einem Server
      Die Methode, Jitter mit zwei PPS-Signalen zu erfassen, ist eine alte Technik, und auch Tempco-Learning gibt es schon seit Jahrzehnten
      Es fehlt jedoch eine Verifikation, wie genau dieses gelernte Tempco tatsächlich ist