【備忘録・Linux×Diretta DDS極限チューニング】GentooPlayer RT環境で挑む「完全コア分離」と「NIC排他制御」による超低ジッター伝送

記事中リンクにはアフィリエイト広告が含まれます。運営費一部補填と、紹介製品の実勢価格・詳細確認が目的で、アフィリエイト目的のサイトではなく、編集方針はそれらの影響を受けません。
スポンサーリンク

本記事は、ネットワークオーディオで人気のある方式Direttaを最新の方式であるDiretta DDSに対応させた際、DirettaHostを組み込んでいる有料LinuxのGentooPlayerを細かい点で音質UPのためチューニングした備忘録です。

筆者のようなプログラミングの出来ない文系の非エンジニアにとって、Linuxをカスタマイズするのは、先輩マニアのサイトなどからやり方をマルコピーするか、ブラウザ上にグラフィカルな管理画面(WEBUI)が提供されている場合かのどちらかでした。またその場合でも、WEB上で知り得た情報に忠実にやるしかなく、応用力はゼロでした。

しかし、AIが普及して状況は一変しました。AIはプログラミングが得意なので、大抵のことをSSHというプロンプト(文字でPCを操作する)で行ってくれます。今回も以下は、AIのGeminiに手トリ足取り教えていただいた記録です。
以下の記事の内容を参考にするというより、何かやりたいことがあったら、AIと一緒にやるという方法があるということを参考にして下さい。

SSHでプロンプトを打つ
スポンサーリンク

実際の方法(内容)

Diretta DDS(Direct Discrete Stream)は、送信側(Host)から受信側(Target)に対して細かく等間隔にオーディオパケットを送り出すことで、Target側の処理負荷変動を最小限に抑え、受動的な低ノイズ動作を実現する通信プロトコルです。

しかし、Linux OS上で汎用的な動作をさせている限り、OSのハウスキーピング(管理処理)、タイマー割り込み、他プロセスのコンテキストスイッチ、そしてネットワークカード(NIC)のパケット合算・省電力機能が干渉し、送出タイミングに微小な揺らぎ(パケットジッター)が生じます。

今回は、GentooPlayer(PREEMPT_RTカーネル)が稼働するFujitsu製PCをプラットフォームに、「CPU物理コア完全分離」「NICハードウェア割り込み排他固定」「ethtoolによるオフロード全廃」「DirettaプロセスのSCHED_FIFOリアルタイム化」を施し、パケット送出パイプラインをOSノイズから物理的・論理的に完全隔離した構築ログをお届けします。

1. チューニングの設計思想(4コアCPUの役割分担)

4コアCPUの内部処理を厳格に役割分担させ、プロセス間競合をゼロにするアーキテクチャを設計しました。

コア役割処理内容
Core 0OS管理・ハウスキーピングカーネルスレッド、タイマー割り込み、SSH、Web UI(Python)を集約
Core 1Player / デコード領域MPDやパイプ転送プロセス用(OS管理ノイズの混入を遮断)
Core 2NIC ハードウェア割り込み(IRQ)eth0の割り込みハンドラを排他アサイン
Core 2, 3Diretta DDS 送出パイプラインDiretta Host送信プロセスをリアルタイムスケジューラで固定稼働

2. 実装手順ログ

① ブートパラメータによるCore 1〜3の完全隔離(isolcpus)

カーネルスケジューラがCore 1〜3へ通常のタスクを割り振るのを禁止し、Tick(タイマー割り込み)を停止させます。

  • Web UIの場合: 「00. Set CPU」から Set_isolate_cpu: 1-3、Set nohz_full rcu_nocbs: enable を設定してEXECUTE。
  • CUI / GRUBの場合: /etc/default/grub の GRUB_CMDLINE_LINUX_DEFAULT に以下を追記し、/boot(/dev/sda2)をマウントして grub-mkconfig -o /boot/grub/grub.cfg を実行。

Plaintext

isolcpus=1-3 nohz_full=1-3 rcu_nocbs=1-3 rcu_nocb_poll kthread_cpus=0 irqaffinity=0
  • isolcpus=1-3: カーネルスケジューラによるコアへの通常タスク割り振りを遮断。
  • nohz_full=1-3: タスク稼働時のタイマー割り込みを停止。
  • kthread_cpus=0 / irqaffinity=0: カーネルスレッドと汎用割り込みをCore 0に集約。

② NICハードウェア割り込み(IRQ 25)のCore 2排他固定

Diretta送信用NIC(eth0)の割り込み番号(IRQ 25 / PCI-MSIX)を特定し、Core 2(ビットマスク値 4)へ固定します。

Bash

# IRQ 25 のアフィニティを Core 2 に固定
echo 4 > /proc/irq/25/smp_affinity

③ NICオフロード機能・バッファリングの完全無効化(ethtool)

一般的なLANカードは効率重視でパケットをまとめて送受信する機能(TSO/GRO等)や省電力制御(EEE)が働きます。これらは小刻みなDDSパケット送出思想と真っ向から衝突するため、全停止させます。

Bash

# パケット合算・オフロード機能の停止
ethtool -K eth0 tso off gso off gro off lro off

# パケットディレイ(Coalesce)をゼロにして即時送信
ethtool -C eth0 adaptive-rx off adaptive-tx off rx-usecs 0 tx-usecs 0

# 省電力イーサネット(EEE)の無効化
ethtool --set-eee eth0 eee off

④ DirettaプロセスのCore 2,3固定とリアルタイム化(SCHED_FIFO 90)

Diretta送出スレッドに対し、PREEMPT_RTカーネル上で最高レベルの優先度(SCHED_FIFO 90)を与え、Core 2,3に束縛(taskset)します。曲の切り替えやフォーマット変更でPIDが再生成されても自動で追従するよう、監視デーモンを起動スクリプトに組み込みました。

  • 自動化スクリプト作成: /etc/local.d/diretta_tune.start

Bash

cat << 'EOF' > /etc/local.d/diretta_tune.start
#!/bin/bash
# 1. NIC Offload 無効化
ethtool -K eth0 tso off gso off gro off lro off 2>/dev/null
ethtool -C eth0 adaptive-rx off adaptive-tx off rx-usecs 0 tx-usecs 0 2>/dev/null
ethtool --set-eee eth0 eee off 2>/dev/null

# 2. NIC IRQ 25 を Core 2 (mask: 4) に固定
echo 4 > /proc/irq/25/smp_affinity 2>/dev/null

# 3. DirettaプロセスのCore 2,3固定 & FIFO 90自動割り当て(バックグラウンド監視)
while true; do
    for pid in $(pgrep -f -i diretta); do
        taskset -pc 2,3 $pid >/dev/null 2>&1
        chrt -f -p 90 $pid >/dev/null 2>&1
    done
    sleep 3
done &

exit 0
EOF

chmod +x /etc/local.d/diretta_tune.start
rc-update add local default

3. 動作検証結果(エビデンス)

① 割り込みの排他固定チェック

音楽再生中の /proc/interrupts を確認した結果です。

Plaintext

# cat /proc/interrupts | grep -E "eth0|25:"
 25:         29          0       1674          0  PCI-MSIX-0000:07:00.0   0-edge      eth0
            Core 0     Core 1     Core 2     Core 3
  • Core 0: 初期化時の29カウント以降、完全に停止。
  • Core 1: カウント「0」。デコード用クリーン領域を維持。
  • Core 2: 「1674」とパケット割り込みが排他的に集中。
  • Core 3: カウント「0」。Diretta送出スレッドの演算専用として完全にクリア。

② プロセス追従のチェック

Plaintext

# for pid in $(pgrep -f -i diretta); do echo "--- PID $pid ---"; chrt -p $pid; taskset -cp $pid; done
--- PID 4227 ---
pid 4227's current scheduling policy: SCHED_FIFO
pid 4227's current scheduling priority: 90
pid 4227's current affinity list: 2,3
--- PID 4441 ---
pid 4441's current scheduling policy: SCHED_FIFO
pid 4441's current scheduling priority: 90
pid 4441's current affinity list: 2,3
--- PID 5170 ---
pid 5170's current scheduling policy: SCHED_FIFO
pid 5170's current scheduling priority: 90
pid 5170's current affinity list: 2,3

動的に生成されたスレッド(PID 5170等)を含め、全Direttaプロセスが SCHED_FIFO 90 かつ Core 2,3 へ自動束縛されていることを確認しました。

4. 試聴インプレッション・音質評価の着眼点

パケットの連続性・等間隔性がナノ秒〜マイクロ秒単位で整い、送信側NICの高周波スイッチングノイズがTarget機へ干渉しなくなったことで、以下の聴感上の変化が得られます。

  • S/N感と背景の漆黒感: 演奏が始まる直前の空気感、ホールの残響成分の消え際(ディケイの階調性)の濁りが払拭され、音場全体の静寂度が一段深まる。
  • 音像の輪郭と彫りの深さ: センターボーカルやアコースティック楽器の輪郭が滲まず、ピンポイントに締まる。余計な付帯音が削ぎ落とされたことによる定位の明確化。
  • 高域のトランジェントと肌触り: ハイハットやシンバルのアタックの立ち上がりが鋭敏になりつつも、デジタル特有の硬さや耳につくザラつきが取れ、自然で滑らかな伸びを獲得。
  • 低域のダンピングと階調感: ウッドベースのピチカートやバスドラムの打撃音において、ボワつきのない引き締まった制動感と、胴鳴りの低域グラデーションが明瞭に描き分けられる。
261015215428262

5. まとめ(YouTube解説動画に向けて)

今回の検証により、Linuxトランスポート機におけるチューニングは「単にリアルタイムカーネル(RT)を導入するだけ」では不十分であり、「OS管理処理の隔離」「NICハードウェア割り込みの制御」「ネットワークオフロードの停止」を三位一体で組み上げることで初めて真価を発揮することが実証できました。

YouTube動画では、ターミナル上のリアルタイム割り込み監視画面(Core 2のみがカウントアップする挙動)の実機キャプチャとともに、空気録音による音質変化の比較をお届けする予定です。

コメント 他者への誹謗中傷はお控え下さい