前回は、分散シミュレーションの課題を少しだけ整理してみました。
今回はその続きとして、箱庭コンダクターが担っている「時刻同期」について書いてみます。
先に断っておくと、
ここでいう時刻同期は、NTPのような時計合わせの話ではありません。
また、DDSやQoSの設定でどうにかなる話でもありません。
箱庭で扱っているのは、
「次の時刻へ進んでよいかどうか」を誰が決めるのか
という、もう少し厄介な問題です。

箱庭が扱う時間について
よく箱庭の話をするときに誤解されてしまうのは、
箱庭が扱う時間は、いわゆるウォールクロック(壁時計)、
リアルな時間ではない点です。
リアルな時間は一方向にしか進みません。
止めることなんて当然できませんよね。
そうではなく、箱庭が扱う時間は仮想時間です。
つまり、シミュレーション時間です。
この仮想時間は、
現実世界の時間とは違って、次のような性質を持っています。
- 進めることができる
- 止めることができる
- 条件が揃うまで待つことができる
言い換えると、
「世界をいつ進めるか」をコントロールできる時間
なのです。

単一シミュレーションの感覚で分散化すると、何が壊れるのか
ここで、シミュレーション時間について、単一プロセスのシミュレーションでやる場合、仮想時間の扱いはそれほど問題になりません。
1ループごとに、
- 入力を読む
- 計算する
- 時刻を進める
これを順に実行するだけで、世界は自然に前へ進みます。
しかし、これらのシミュレータを
分散した環境で接続した瞬間、話は変わります。
- あるノードは、すでに次の時刻を計算している
- 別のノードは、まだ前の時刻を処理している
- さらに別のノードは、通信遅延で情報が届いていない
といった状態が、常に発生します。
それぞれのノードから見れば、「自分は正しく動いている」。
しかし、この状態で各ノードが
自分の判断で次の時刻へ進んでしまうと、
世界全体としての整合性は簡単に壊れます。

問題は
「誰かが遅れていること」や
誰かが早く進んでいること」ではありません。
問題なのは、
全体として、
整合が取れた状態で
シミュレーションを進めるための
仕組み・構造が存在しないこと
だと思います。
単一プロセスでは、
この判断は暗黙のうちに
ループ構造そのものが担っていました。
分散環境では、
その判断を 構造として明示的に用意する必要があります。
そこでコンダクターが登場する
箱庭コンダクターが担っているのは、まさにこの部分です。
- 各ノードがどこまで進んでいるかを把握し
- まだ待つべきか
- 次の時刻へ進んでよいか
をまとめて判断します。
また、箱庭アセットは
箱庭コンダクターの世界時刻を参照し、
自分のシミュレーション時刻が
それを超えない範囲では自由に動き、
時刻を進めることができます。
このような相互協調による時刻制御が、
箱庭における
「世界を進めるための合意形成」
です。この役割は、単なる同期というより、
時刻の調停(Time Arbitration)
に近いものです。

そして、その調停の結果として、
同一マシン内で複数の箱庭アセット(プロセス)が動作する場合、
それぞれのアセット間の時刻のずれは、
必ず一定時間内(最大許容遅延時間)に収まることが、
数学的に証明されています(平鍋さんのおかげです)。
この点を説明している資料が、
「箱庭(Hakoniwa)Time」
です。

ここで重要なのは、
箱庭の時刻同期が
「経験則」や「チューニング」ではなく、
構造として“壊れない範囲”を定義している
という点です。
さらに、この構造をそのまま拡張することで、
複数マシン間にまたがる場合でも、
アセット間の時刻差は
最大でも 2 × d_max 以内
に収まることがわかりました(数学的な証明はそのうち)。
単一プロセスから分散環境まで、同じ考え方で世界の整合性を保てる。
これが、箱庭コンダクターの時刻同期設計のポイントです。
次回は、この時刻同期を実現するための
箱庭コンダクターの内部設計と実装について、
もう少し踏み込んで説明していきたいと思います。
つづく。

コメントを残す