1 ポイント 投稿者 GN⁺ 2025-11-27 | 1件のコメント | WhatsAppで共有
  • Raspberry PiベースのNTPサーバーの周波数変動を減らすため、CPUコアの固定と熱安定化を組み合わせた実験結果を紹介
  • CPU温度の変化がクリスタルオシレーターの周波数ドリフトを引き起こすことを観察し、これを一定温度に保つことで安定化
  • PID制御ベースのtime burnerプロセスでCPUを54°Cに維持し、周波数変動81%減少標準偏差77%減少を達成
  • CPU 0をchronyd専用に固定し、残りのコアで熱負荷を維持することでNTPオフセットを平均38ns水準まで改善
  • 高精度な時刻同期や科学機器など、極限の精度が必要な環境で低コスト高精度タイミングサーバーを実現できる可能性を提示

問題: 温度変化によるタイミングの不安定さ

  • Raspberry Piの**動的周波数制御(DVFS)**機能は電力効率には有利だが、高精度な時刻同期には不利
    • CPU負荷に応じてクロック周波数が変わると、システムクロックのティック速度も変動
  • クリスタルオシレーターの周波数は温度に敏感で、CPUの発熱に応じて数ppm単位で変動
    • 昼夜の温度変化に応じて周波数ドリフトが発生
  • Grafanaのモニタリング結果では、CPU温度の変化に応じて約±1ppmの周波数オフセットが観測された
    • RMSオフセットの平均は86ns水準で、改善の余地があった

発見: 一定温度を維持する効果

  • CPU温度を一定に維持すると、周波数安定性が向上する可能性を確認
  • 解決策は2つで構成
    1. CPUコアの分離 – chronydとPPS割り込みをCPU 0にのみ割り当て
    2. 熱安定化 – 残りのコアを継続的に稼働させて一定温度を維持
  • 2025年11月17日09:10に熱安定化システムを有効化すると、周波数の振動が即座に減少した

解決策1: CPUコア固定とリアルタイム優先度の設定

  • CPU 0: chronydとPPS割り込み専用
  • CPU 1–3: 一般処理および熱負荷維持用
  • 起動時に自動実行される最適化スクリプトを構成
    • CPU周波数制御モードをperformanceに固定
    • PPS IRQ(200) をCPU 0に固定
    • chronydをリアルタイム優先度(SCHED_FIFO 50) に設定
    • ksoftirqd/0プロセスの優先度を向上
  • スクリプトは/etc/rc.localまたはsystemdサービスとして登録可能

解決策2: PID制御ベースの熱安定化

  • CPU温度を一定に保つためPID制御ループを使用
    • 目標温度: 54°C
    • CPU 1–3上で3つのワーカープロセスがMD5ハッシュ計算で負荷を生成
    • PID出力値に応じて計算時間と待機時間を調整
  • PIDパラメータ
    • Kp=0.05, Ki=0.02, Kd=0.0
    • 温度変化が遅いため微分項(Kd)は0
  • 結果としてCPU温度は±0.2°Cの範囲内で安定して維持された

結果: 周波数安定性の向上

  • 周波数変動性81%減少標準偏差77%減少RMSオフセット49%減少
  • 平均RMSオフセット: 85.44ns → 43.54ns
  • 中央値RMSオフセット: 80.13ns → 37.93ns
  • CPU温度を54°Cに維持した状態で**±0.14ppm範囲の周波数安定性**を確保
  • 室温変動(18.9~22.2°C)にもかかわらず安定性を維持

設定手順

  • 事前準備: GPS PPSベースのNTPサーバー構築が必要
  • 必須パッケージのインストール
    • 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 を確認
    • chronydのCPU固定と優先度を確認
    • chronyc trackingでRMSオフセットを測定 (例: 35ns水準)

モニタリングとトラブルシューティング

  • リアルタイムモニタリング: 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リソースの占有: 4コア中3コアを使用
    • NTP専用機器には適しているが、複数サービス環境には不向き

適用可能な分野

  • 高精度な時刻同期科学機器分散システム研究ネットワークテストなど
  • 一般用途には過剰だが、低コストで高精度な実験環境の構築には有用

今後の改善方向

  • 適応型PIDチューニングで季節ごとの温度変化に対応
  • ハードウェアベースの冷却制御(PWMファンなど)で電力効率を改善
  • **OCXO(恒温槽制御水晶発振器)**を適用すれば熱ドリフトを除去可能

結論

  • CPUコア固定とPID制御による熱管理の組み合わせで超高精度NTPサーバーを実現
  • 周波数安定性81%向上、RMSオフセット38nsを達成
  • 実験を通じて熱管理とリアルタイムスケジューリングの相関関係を実証
  • 実用性よりも技術的探求と学習価値を重視したプロジェクト

1件のコメント

 
GN⁺ 2025-11-27
Hacker Newsの意見
  • CPU0を避けて、カーネルコマンドラインに idle=poll を設定すると、より高い精度が得られる
    CPU0にはほかの割り込みが集中するため、高いタイミング精度が必要な処理には向いていない
    • 私も同感です。私たちの DebianベースのOSディストリビューション でも、周波数スケーリングの無効化やコア固定など、似たような最適化を行っています
      CPU0には移せないシステム作業が多いので、ほかのコアを 隔離された島(isolated core) として使うほうがずっと良いです
      私たちの隔離コアのスケジューラ遅延(latency)は、最小 1µs、平均 5µs、最大 59µs 程度で、非常に安定しています
    • いいヒントです。今日あとで自分でも試してみるつもりです
  • WWVB送信所 では、温度変化を防ぐために何百本もの水のボトルで機器を断熱している
    関連記事: Spare Time – JILA
    • そのページは単独で共有する価値があります。原子時計4台 を運用しながら、UPSが自動車用バッテリー2個とヘッドライト2個で構成されている点が本当に印象的です
      水のボトルで作った熱容量(thermal mass)も興味深いです
    • 私も似た方法を使っています。断熱された物置の机の下に水をためて、夜のあいだ凍らないようにしています
      まるで寝袋の中に 温かい石 を入れるのと似た効果です
  • 私は Austin (austinsnerdythings.com) です。昨夜記事を投稿して寝て、起きたらHNで1位になっていて驚きました
    私の LEA-M8T は16Hzでタイムパルスを生成し、chrony設定では dpoll=-4 にしています。16秒間隔で256サンプルを集めて、安定性が向上しています
    机の横には BH3SAP GPSDO もあります。Claudeがファームウェアを修正し、GPS PPSがなくてもパルスを出し続ける flywheelモード を追加しました
    さらに、TSIP(Trimbleプロトコル)出力をサポートするように更新しました。関連内容は次の記事で扱う予定です
    コメントへの返信もまもなく付ける予定で、質問はいつでも歓迎です
    • いい記事をありがとう。私も似たセットアップをしているので、とても参考になります
      16Hzパルスが実際にどれほど違いを生むのか気になります。それと、データを influxdb にどう入れているのかも知りたいです。私は collectd を使っていますが、情報があまりありません
    • すばらしいプロジェクトです。もし Raspberry Piをケースに入れているか も気になります
      金属ケースでもあれば、暖房やエアコンによる周期的な温度変化から、より安定した結果が得られるはずです
  • 安価なPiのオシレータ水晶を TCXO に交換すると、周波数の安定性が大幅に向上する
    関連資料: Raspberry Pi StackExchange – oscillator 交換
    これだけでもドリフトが4〜5倍減る。ほかの手法と併用するとさらに良い
    • その投稿は何度も読みました。Pi4向けの OCXO付きオーディオファイル向けHAT も売られています
      ただ、はんだ付けの腕に自信がないので、自分で交換するのは難しそうです
    • TCXOの価格 は意外と安いです。Abracon製品の一部は2ドル未満でした
  • これは SBCスケールのOCXO だ。より大きなヒートシンクを付けたり、オシレータの周囲に 熱容量(thermal mass) を追加したりすると役立つのか気になる
    単にNTPサーバーを立てるだけの作業からでも学べることは多い
    • Flirc金属ケース を勧めます。CPUがケース本体に密着して、大きな熱容量を形成します
      ファンなしでも優れた 受動冷却 が可能です
    • 私も同じように考えています。CPUとオシレータの上に金属ブロックを載せて 熱慣性 を高めると良さそうです
      温度がゆっくり変われば、クロックドリフトもゆっくり変化するので補正しやすくなります
      ただし、小さなヒートシンクはかえって周囲温度の変化に敏感になるかもしれません
    • Piのケースに 断熱材を追加 することも考えています
      室温の急変(窓を開ける、シャワー後の湿気など)を和らげ、CPUが不必要に熱を出すのを減らせます
      結局のところ、目標は熱を一定に保つことです
    • ただし、あまりに多く熱を逃がすのは逆効果かもしれません
      ほかのコアはすでに最大温度近くで動作していて、温度に応じてクロック速度を自動調整しています
      過度な冷却は、この 自己温度制御メカニズム を妨げる可能性があります
  • 水晶に 抵抗と発泡断熱材 を取り付けて直接加熱する方法もある
    GPIOで制御可能なトランジスタを追加して、PID制御 で温度を維持することもできる
    • これはほぼ100年前から使われてきた方式です。1950年代の クリスタルオーブン は、小さな金属箱の中をおよそ75°Cに保っていました
      温度係数(temperature coefficient)が0に近くなるようにカットされた水晶を使っていたため、安定していました
      最近の機器でもなおこうした構造が使われており、完全に安定するまで約5分かかります
    • 私も以前、Piを 梱包用フォームの上に載せる実験 をしたことがあります
      周囲温度の変化は減りましたが、結局は 温度制御チャンバー に入れるのが最も確実な解決策です
  • わざわざCPUを燃やして温度を維持するより、マイクロコントローラと高精度オシレータ を使うほうがよいのではないかと思う
    たとえばSTM32ボードにイーサネットをつないでNTPサーバーとして使えば、より安定しそうだ
    • 私もそれを持っています。eBayで70ドルで買った BH3SAP GPSDO で、修正版ファームウェアにより flywheelモード をサポートしています
      PiにNTP信号を供給できますし、STM32でも可能ですが、基本的にイーサネット機能はありません
    • 一般的にNTPは 時間に敏感なプロセス なので、SoCよりMCUのほうがはるかに安定しています
      RTLinuxには、外部ピンの状態に合わせてスケジューラを同期させる機能もあります
      ただし、プロセッサが多くなると メタ安定性(metastability) の問題が出てきます
      PiはFPGA(Zynq)のようなリアルタイム保証を提供しません
  • SoCの温度を一定に保つために 意図的に負荷をかける発想 は思いつかなかった
    でも消費電力が低いので、複雑な冷却システムの代わりに少し電力を無駄にして解決するのは合理的だ
  • 2022年に関連する 論文 があった: USENIX NSDI22 – Najafi
    • 興味深い論文でした。温度応答曲線のモデリング によって、CPUを燃やす代わりに、より洗練された形で問題を解決しています
    • ただ、その論文はサーバー内の 温度センサーの多様性 を観察した程度です
      PPS信号2本でジッタを検出する方法は昔からある技術ですし、温度係数学習(tempco learning) も何十年も前から存在しています
      実際にその学習済みtempcoがどれほど正確なのかについての検証は欠けています