Ping とレイテンシー
WoT の ping とレイテンシーの話。 WoT の ping 表示は何を調べて何を表しているのか、 レイテンシーとはどう関係しているのか、についてまとめました。
はじめに
WoT の Ping とは何を指しているのか
ping を知っていますか?
そう、WoT 戦闘画面の左上に出てくるアレのことです。 下のスクリーンショットだと 288 ms (ミリ秒)、0.288 秒ですね。 これは EU サーバで記録したのであまり ping はよくありません。 日本から香港 (HK) サーバだと 60 ~ 100 くらいだという人が多いのではないでしょうか。
この ping が表している数字は何なのか、 というのがこの記事のテーマになります。
もちろん、ping が表示しているのは通信の遅延時間だという理解でよいのですが、 ここのところをもう少し掘り下げていきます。
本題に入る前に断っておきますが、 この記事を読んでも WoT が上達することはまったくありません (そんな勘違いをする人はいないと思いますが)、 ping 改善の参考になることもおそらくないでしょう。 ping の悪化が気になるのであれば下に示す公式のプレイヤーサポートページを参照してください。 この記事は一般のプレイヤーにとってはただの雑学くらいの位置づけになるかと思います。
クライアントとサーバーの通信
WoT クライアントはサーバーとどのように通信しているのでしょうか。
WoT はマルチプレイヤーのネットワークゲームなのでサーバーと常時通信を行っています。 通信状態の良し悪しがゲームのプレイ環境に影響を与えるので、 WoT クライアントでは戦闘中に現在の状態をモニターできるようになっています。 それが先のスクリーンショットで示した ping の表示ですね。
ここでいう ping 値とは、通信の遅延を表しています。 表示している ping の値は実際に計測した値をもとしていますが、 通信の遅延が直接計測されるのではありません。 ping を計測するとき、クライアントとサーバーの間では 下の図のようなやり取りが行われています。
レイテンシー (latency)
クライアントはサーバーの状態を直接知ることはできません。 そのため、上の図のやり取りでクライアントが知ることができるのは、 ping 計測のためにサーバーに情報を送信した時刻 $T_1$、 そしてその応答を受信した時刻 $T_2 $ のみです。
クライアントがサーバーに要求を送信 ($T_1$) してから、 サーバーからの応答を受信 ($T_2$) するまでの遅延時間 ($T_2 - T_1$) を計算します。 この遅延時間 $t_\text{latency}$ はレイテンシー (latency) と呼ばれています。
\[t_\text{latency} = T_2 - T_1\]サーバーティック (server tick)
サーバーはクライアントからの情報を受信した直後に応答を返すのではなく、 応答を返すまでに時間のずれが生じます。 サーバーは一定の時間間隔であるサーバーティック (server tick) を基準に処理を行うようになっていて、 応答を返すタイミングもその影響を受けるからです。
サーバー側での応答遅延 (サーバーが要求を受信してから応答を送信するまでの遅延) の主な要因に、 このサーバーティックによる遅延があります。
この遅延時間は、 サーバーに要求が到着したタイミングによるため予測することは困難です。 ただし、要求を処理する時間を必要としない場合 (サーバーの処理に余裕がある場合) には、 この遅延時間はサーバーティック以下であることが期待できます。
サーバーティックを $t_\text{tick}$、 サーバーティックによる遅延時間を $\Delta t_\text{tick}$ とすると、 下式の関係があります。
\[0 < \Delta t_\text{tick} \leq t_\text{tick}\]サーバーティックの具体的な長さに関する情報は
constants.SERVER_TICK_LENGTH
に設定されていて、
0.1 秒です。
サーバーが 0.1 秒間隔でしか処理しないのではラグがひどくなるのではないか、 と心配する人がいるかもしれませんが、 車輌の操作情報などは、サーバーが受信してから時間をさかのぼって計算するので、 少なくともサーバーティックの範囲内であれば通信遅延による直接的なラグは生じないと考えられます (ただし、クライアント側の車輌の動き予測とサーバーとのずれは生じます)。
通信遅延 (ping)
ここでの ping はクライアントとサーバーとの通信にかかる時間 (通信遅延) を指します。 つまり、レイテンシーからサーバーティックによる遅延を除いた時間のことです。
ping とレイテンシーの関係をまとめると下式のようになります。 $T_1$, $T_2$ はそれぞれサーバーへの送信時刻と受信時刻、 $t_\text{latency}$ がレイテンシー、 $t_\text{ping}$ が通信遅延 (ping)、 $\Delta t_\text{tick}$ はサーバティックによる遅延時間です。
\[T_2 - T_1 = t_\text{latency} = t_\text{ping} + \Delta t_\text{tick}\]レイテンシーには、 往復の通信にかかる時間 (ping) に加えて、 サーバーが受信してから送信可能になるまでの時間 (次のサーバーティックまでの時間) が含まれることになります。
レイテンシーの計測と ping の推定
レイテンシーの計測と平均化
通信状況の変化によって刻々と ping は変動し、 レイテンシーも変動します。 そのため、クライアントで収録するレイテンシーは 1 回の測定で決定したものではなく、 過去複数回の測定結果を平均した値が用いられます。
計測したレイテンシーは
BigWorld.LatencyInfo()
で取得できます。
結果として渡される LatencyInfo オブジェクトには、
レイテンシの現在値、最小、最大、平均の4要素が含まれますが、
現在のところ、すべて同じ値で、クライアントで使用されるのは平均のみのようです。
ping の推定 (サーバーティックの影響除去)
レイテンシーから ping を推定する例が Avatar.__reportLag()
にあります。
ping = BigWorld.LatencyInfo().value[3] - 0.5 * constants.SERVER_TICK_LENGTH
これを先の式の記号を使って表すと下式になります。 $\hat t_\text{ping}$ は ping の推定値、 $\bar t_\text{latency}$ は計測によって得られた平均レイテンシー、 $t_\text{tick}$ はサーバーティックの値 (定数) です。
\[\hat t_\text{ping} = \bar t_\text{latency} - t_\text{tick} / 2\]$t_\text{tick} / 2$ は $\Delta t_\text{tick}$ の期待値を求めていることに相当します。 クライアントとサーバーが完全に非同期で動作している場合、 $\Delta t_\text{tick}$ は $0$ からサーバーティック $t_\text{tick}$ の範囲で一様に分布していると考えられるので、 $\Delta t_\text{tick}$ の期待値は $t_\text{tick} / 2$ になります。
このようにして求められた ping 推定値を WoT クライアントは ping として表示しています。
補足情報
ping 表示の更新間隔
ping 表示の更新間隔は
gui.battle_control.controllers.debug_ctrl._UPDATE_INTERVAL
で定義されていて、
値は 0.2 秒となっています。
ping の表示単位
クライアントに表示される ping の単位は ms (ミリ秒) です。 レイテンシーなどは浮動小数点数で表した秒単位で計算されているので、 ping の値は計算した結果を 1000倍して小数点以下を切り捨てます。
ミリ秒で表すと、 サーバーティックは 100 ms、 表示の更新間隔は 200 ms ということになります。 画面の更新は FPS 60 だと 約 16.7 ms で、 1 サーバティックに対し 6 回の描画が行われていることになります。
実測による確認
ASIA サーバーでの ping 計測結果と、レイテンシーから計算した値との差を示します。 戦闘開始後、ping 値が安定してから 60 秒間の記録で、 計測間隔は約 0.2 秒です。 計測には mod dispersionindicator を使用しました。
ping の値は 60 ~ 100 ms の間で変動していて、変動幅は比較的大きいようにみえます。
ping の値と、レイテンシーから計算した値との誤差 (error) を求めてみると、 最小 -6、最大 5 でした。 クライアント内で ping を計算するタイミングと、 mod を使用してレイテンシーを取得するタイミングが異なるので、 誤差が生じる場合がありますが、おおむね一致しています。 ミリ秒単位の整数値に丸める方法も、最近接丸めではなく、 切り捨てであることも確認できます (グラフは切り捨てとの差を表示しています)。
同様に、EU サーバーでの計測結果です。 ping の値は 240 ~ 320 ms の間で変動しています。
22秒から33秒まで ping の変化が見られない区間がありますが、 これは車輛の操作を行っていない時間に対応します。
このことから、車輛の操作を行っていないときは ping の値も更新されないことがわかります。 ping の計測 (レイテンシーの計測) が単独で行われているのではなく、 車輛の操作情報の送信とともに行われているためです。
まとめ
以上をまとめると、次のようになります。
- WoT クライアントの遅延 (レイテンシー) には通信による遅延とサーバーの応答による遅延が含まれる
- クライアントは計測したレイテンシーから通信による遅延を推定し、ping として表示している
- レイテンシーは瞬間の値ではなく平均値を用いている
- クライアントからの要求の到着とサーバーティックとのタイミングのずれにより、サーバーの応答遅延が生じる
- サーバーティックとのタイミングのずれは偏りがないものと仮定して ping を推定している
普段なにげなく見ている ping 値ですが、 こうして整理するといろいろなことが見えてきました。 ゲームのプレイには何の役にも立ちませんが、 WoT の挙動の解析をする際には知っておくとよいかもしれません。