ステラリス 開発者日記 第181回 スレッド化とロード時間

スポンサーリンク
更新情報

2020/8/29 フォーラム内のやりとりを追記


パラドックス社の公式フォーラムに
ステラリスの開発者日記 第181回が掲載されています。

Stellaris Dev Diary #180 - DLC Visibility Experiment
Hello everyone!We hope you are enjoying your time with 2.7 and the 4 year anniversary of Stellaris! It’s very fun to see how far the game has come, and just as ...

なんと前回第180回は5月半ばだったので3ヶ月半ぶりになるナンバリングの開発者日記となります。

今回はステラリス開発陣がこの夏にいったい何に取り組んだのか?というトピックのようです。

以下パラドックスフォーラムの内容を意訳したものとなります。
※画像等はフォーラムより引用。
スポンサーリンク

ステラリス 開発者日記 第181回 スレッド化とロード時間

今回の担当はステラリス・プログラマーのMatRopertさんです。

冒頭のあいさつ

フランスのパラドックスから、みなさん、こんにちは。

ステラリスのチーム全員を代表して、皆さんの現在の状況が良好で楽しい夏休みを過ごしたことを願っています!

私達はまだオフィスに出社はしていませんが全員が仕事へ戻りました。
たくさんの面白いニュースがあり、とてもエキサイティングな秋・冬になりそうです!
今後数週間から数ヶ月の間、みなさんとこれらについてのニュースを共有できることを非常に楽しみにしています!

今日は、私たちプログラマー陣が夏に取り組んできた技術的なことをいくつか紹介して、Ver 2.8リリースについて初の概観を公表します。
チームの残りのメンバーが次回の開発者日記で、今後のコンテンツと機能についてさらに明らかにする予定です。

では前置きは抜きにして、スレッド化について話しましょう。

スレッド?スレッドとはなにか?

果たしてVictoria IIIと複数のスレッドを使ったParadox社ゲームのどちらが先に来るのか、ファンはいつも疑問に思っているというジョークがあります。

私は(再び)この神話を払拭しなければならないと思います。
つまり、現在生産されているすべてのParadoxスタジオ製のゲームは、EU4からCK3までスレッドを使用しています。ステラリスもです!
このミーム(管理人注:⬆で出てきたビクトリア3と複数スレッド云々というジョークのこと)がどこからやって来ているのかを説明するには少し歴史を見てみる必要があります。皆さんは歴史が好きでしょう?

ソフトウェア業界は長い間「ムーアの法則」に頼ってきましたが、この法則によると、今後2年で製造されるCPUの効率は現在の約2倍になると言われます。

これは、CPUが50MHzから1GHzになった1990年代に特に当てはまりました。
この傾向は2005年に3.8GHzに到達するまで続きました。
その後クロックスピードは伸びなくなりました。その後の15年間CPUの周波数はほぼ同じです。

結局のところ物理法則により、3~4GHzを超える速度に上げるのは非常に非効率的でなのです。
そこでメーカーは別の方向に進み、CPUをいくつかのコアとハードウェアスレッドに 「分割」し始めました。
このため、今日ではCPUのコア数をチェックしますが、周波数のチェックにはあまり時間をかけません。
ムーアの法則はいまだ有効ですが、戦略的に言えばCPU業界は背を高めようとしているうちに頭打ちになり、方向性変えて幅広になるように変わりました。

このシフトはソフトウェア業界を大きく変えました。
高速なCPU上で高速に動くコードを書くのは簡単なことで、ほとんどのコードは自然にそうなるからです。
しかし、スレッドやコアを利用するのは別の話です。
プログラムというのは複数のコア上で同時に実行できるよう、魔法のように作業を2つ、4つ、または8つに「分割」するわけではありません。
それを中心にして設計するかどうかはプログラマー次第です。

どこにも早くスレッディングしない

このことは私たちのゲームと、私たちがフォーラムで読み続けている懸念を思い出させますつまり「このゲームはスレッドを使っていますか?」です。
答えはもちろんイエスです!
実際、私たちは2コア以下のマシンではゲームがスタートしないという重大な問題を、数回前のリリースにおいては抱えていました。

しかし、問題の本質は「スレッドを効率的に使用していますか?」だと思います。
そして、その答えは「場合によりけりだ」です。
前述したように、より多くのコアを効率的に使用することは、より多くのクロックサイクルを使用することよりもはるかに複雑な問題です。
この例では、スレッド間で作業を分散させる際に克服すべき主な課題が2つあります。それは、順序付け(シーケンス)と発注(オーダリング)です。

シーケンスの問題は、2つの計算が同時に実行されている場合に、同じデータにアクセスする必要がある場合に発生します。
例えば、Prikkki-TiとBlorgという2つのpopの生成を計算しているとしましょう。
彼らは両方とも現在のエネルギー備蓄量にアクセスし、そこにエネルギー生産量を加算して、その値を書き戻します。
シーケンスによっては、初期値(例えば100)を読み込んで、生産量(例えば12と3、Blorgは今日は調子が悪かった)を追加して書き戻すことができます。
理想的には私達はは115 (100+12+ 3)で終わりたいと考えています。
しかし、潜在的には両方とも100を読み込んで計算し、112または103としてお互いの数値を上書きします。

これを回避する簡単な方法は「ロック」を導入することです。Prikkki-Tiの計算が終わって新しい値を書き戻すまでエネルギー値を「ロック」し、Blorgは順番に自分の値を追加します。
この事は問題を解決しますが、より大きな問題が発生します。
つまりアクションが再びシーケンシャルになり、並行スレッドで行う利点が失われます。
さらに悪いことに、ロック、ロックの解除、同期化のコストがかかるため、最初に同じスレッドで両方を計算した場合よりも時間がかかります。

2番目の問題はオーダリング、「順序依存性」です。つまり操作の順序を変更すると導かれる結果が変わる場合があります。
例えば、私たちが先程取り上げたPrikki-TiとBlogが、紛争を友好的な方法で解決しようと決めたとしましょう。
戦闘システムが両方の戦闘員を処理することは分かっていますが、何百もの戦闘行為が行われる可能性があるため、どちらが先に行われるかは分かりません。
また、2台のマシンでは順番が異なります。
たとえば、サーバではPrikki-Ti側のアクションが最初に実行され、クライアントではBlorgアクションが最初に実行されます。

Blogが先に撃った場合

サーバ上では、まずPrikki-Tiのアクションが解決されBlorgが死亡します。
その後のBlorgのアクション(別のスレッド上にある可能性があります)は、死んだBlorgsが射撃できない(それは科学的な事実である)として廃棄されます。
しかし、クライアントは別の方法で計算を配布し(サーバよりも多くのコアを搭載している可能性がありますので)、Blorgが最初にPrikkki-Tiを射撃し、今度は反撃できなかったとします。
このように両者の現実が異なると、とても恐ろしい「プレイヤーの同期がとれていません」というポップアップが表示されるのです。

もちろん、問題を解決する方法はありますが、通常は両方の制約を満たす方法で設計をやり直す必要があります。
例えば最初のケースでは、各スレッドで各帝国に追加する各ポップの生産出力を保存し、最後にそれらを統合することができます。
同じ方法で、私たちの二人の決闘者間の問題は、ダメージをすぐに記録することによって解決することができますが、別のフェーズでその効果を適用し確定的順序のオーダーを取り除く必要があります。

ご想像のとおり、既存のシステムを改造するよりも、スレッド化を念頭に置いて設計する方がはるかに簡単です。
もし私が言うことを信じられないのであれば、皆さんの艦隊の改造にどれだけの時間が費やされているかを見てください。私は待ちましょう。

朗報

さてこれらはとても良い事ですが、では次のパッチでは具体的に何ができるのでしょうか?
これらの仕組みを私たちのエンジンの最も古い部分の1つである、ファイルとアセットのロードシステムに適用するために時間を費やしたことを聞いてみなさんが喜んでもらえれば幸いです。

私達はこの問題に対処するため、長い間サードパーティ製のソフトウェアを使用してきました。
これにより多くの問題が解決されましたが、スレッド化については非常に苦手であることもわかりました。
コア数が多いほうが少ないよりも遅くなることもあり、これは前に述べたロックの問題が最も顕著でした。
他のいくつかの最適化と併せて、ゲームのスタートアップ時間を大幅に削減することができました。
その理由を説明するのには1,000ワードを費やすかもしれませんが、このビデオの方がうまく説明できていると思います。

この比較は、私の自宅のPCで行ったもので、Core i7 2600KとSSDドライブを使っています。
どちらもホットスタートアップ(直前に一度ゲームを起動させている)だったが、私の実験では「コールド」スタートでも大きな違いがあることがわかりました。

※管理人補足
ホットスタートアップは、一度ステラリスを起動→終了させ、再度ステラリスを起動した状態。
コールドスタートアップは、まっさらな状態から初回の起動の事を指してると思われます。

最高のスピードアップを実現するには、新しいベータ版DirectX11レンダリングエンジンを使用する必要があります。
次のパッチではオープンベータ版が提供され、古いDirectX9のレンダラーをより最新のDX11バージョンに置き換えます。
視覚的には同じことですが、DX11を使用してグラフィックスをレンダリングすることで、DX9では困難または不可能だったマルチスレッドの最適化が可能になります。
古いレンダラーでプレイしても、起動時のスピードアップは変わらず、スプラッシュ スクリーンのステップはずっと速くなりますが、ゲームがモデルやテクスチャをロードしたときに、プログレスバーがDX11版のように「ジャンプ」することはほとんどありません。

これらの最適化の一部はClausewitzエンジンの新しいバージョンにも適用されており、CK3(クルセイダーキングスIII)リリース時にもその一部になる予定です。
Imperator(:Rome)もまたその恩恵を受けるでしょう。
EU4やHoI4にも応用できるかもしれませんが、私のEU4での実験ではStellarisやCK3のように大幅な高速化は見られませんでした。

Stellarisの高速化に適用された最適化に関する技術的な詳細については、私のブログに最近掲載した記事を参照してください。

PhysFS performance, a story of threading and locking · Mathieu Ropert
How threading and locking can drastically affect the performance of your C++ program. Case in point: PhysFS.

ではこれにて今日はここまでです。
私は来月、HoI4プログラマーを率いるチームへ異動するので、これが私のStellarisでの最後の開発日記になるでしょう。これらの最適化は私のお別れの贈り物だと考えてください。
私にとってステラリスでの時間は短いものだったかもしれませんが、心配しないでください:私が出て行っても、Jeffが皆さんのために残っています!


以上

フォーラム内のやり取り(Q&A)

フォーラム内のやり取りで気になったものを紹介。
解答側は本文に引き続きステラリス プログラマーのMatRopertさんです。
(他の開発者の発言もありましたが特にどうという事もない内容だったのでカット。)

Q:この更新はベータ版なのか

A:このパフォーマンス更新以外にも2.8パッチまでにまだ内容があります。将来の日記で紹介します。


Q:この改善がEU4にあまり効果がなかったのはなぜですか

A:EU4のアセットには履歴データベースの形式でテキストファイルが多く含まれているためだと思われます。これはWindowsのファイルシステムに起因する別のボトルネックになっています。一方ステラリスでは履歴データベースを持たない、小さなテキストファイルを採用しています。


Q:今回の改善作業とDirectX11への移行はゲームの起動時間以外にもパフォーマンス上の利点がありますか?

A:セーブゲームをロードする時に利点があります。


Q:今回の開発者日記とは関係ありませんが、以前発表された軍事AIが考えていることを表示できるコンソールコマンドdebug_aiはどのようにして使うのでしょうか?

A:現在のリリースバージョンにすでにその機能は含まれています。オブザーバーモードに切り替えてAI国家を観察する必要があります。

これに関する続きのQ&A


Q:何かを誤解していなければ、コマンド自体は入力されているかもしれませんが、実際には何も起きません。
少なくとも、過去の開発者の日記にあったような素晴らしいツールチップは表示されません。

A:ツールチップを表示するには、特定のAI国を観察しつづける必要があります。

AI(そしてそのパフォーマンス)については常に念頭に置いているものです。
次のパッチには、そのトピックに関するいくつかの微調整が含まれる予定です。
これは私たちが時間をかけて取り組んでいる繰り返される課題であり、すべてを一度に解決する唯一のパッチがあるとは思えません。

更に続きのQ&A


Q:特定のAI国家を観察するにはどうすればよいですか?このフォーラムで誰かツールチップを例示することができますか?

A:オブザーバーモードで、帝国の旗をCtrlキーを押しながらクリックし、それを観察します。
画面右上のオブザーバーアウトライナーを使用することもできます。


Q:DirectX11になることでLinux版のステラリスに与える影響はありますか。

A:DirectX11はウインドウ外のことには作用しません。また我々のエンジン開発チームは新しいゲームに対してVulkanとDirectX12の実験をしていますが、私の知る限りそれらをステラリスに対応させる計画はありません。


Q:将来の拡張(DLC)のための機能を設計するとき、ゲームの技術的な制限についてもっと注目する予定がありますか?
ゲームはメガコープDLCが登場する前よりもずっと重いです。
新機能はすごくいいかもしれませんが、ゲームの終盤が現在と同じくらい遅いとしたら、それほど楽しいとは思いません。

A:ゲームスピードの問題については承知しています。

ここで少しはっきりさせておきます。
通常、機能というものはゲームのパフォーマンスが変化する理由ではありません。
メガコープによる大きな影響は、無料パッチにおける人口システムの再設計によるものです。
最近の銀河では、シミュレーションする人口が少なくとも4~5倍になり、コストがかかります。
今回、起動速度を最初に検討した理由については、まず開発者が開発中にゲームをとても多くの回数再起動するためです(1日に20回以上と考えてください)。
つまり起動速度の改善により、開発の生産性が大幅に向上します。
2番目には、この機能は他のゲームタイトルとも共有できるため、Stellarisチームだけでなく、ほとんどのParadoxスタジオにとって価値があるためです。


Q:今回の改善はゲームスタート時でもゲーム内でも効果があるのですか

A:これらの変更は、純粋に読み込み時間に関するものです。
先に述べたように、ゲーム内の速度は完全に異なる要因によって制限されます。


Q:次の開発者日記では、Ver 2.8そしておそらくDLCのコンテンツに関する情報がありますか?

A:2.8アップデートの内容については、今後の開発日誌で詳しく説明します。
そして、それは主にジェフについてとなります…。


Q:ステラリスのプログラマーは、ゲームプレイ自体の速度ではなく、ゲームの起動速度を上げるためだけに夏の間ずっと働いていたのか?
または、ゲームプレイ自体に行われた最適化を詳細に説明する、別の最適化開発について今後発表されるのでしょうか?

不躾で申し訳ありませんが、たとえゲームの起動が速くなったとしても、ゲーム自体が速くなるわけではありません。

A:私たちが取り組んだのはこれだけではありません。これは、夏の後半に少し外部からの助けを借りつつ私が取り組んだものです。


Q:ホストマシンですべてを計算し、クライアントにデータをストリーミングしないのはなぜですか?

A:これは時々出ては消えるアイデアです。
実際には、更新中に変更されたデータを識別する効率的な方法と、それをネットワーク経由で送信する別の効率的な方法が必要になります。
これまでのところ、この方式がより効率的であると証明される多くの経験的な証拠は確認されていません。


今回は以上です。
その他もいくつかありましたが、あまり直接関係ないような内容だったのでカットしましたm(_ _)m

※フォーラムの5ページまでチェック。

感想・まとめ

以上、Stellaris 開発者日記 第181回の紹介でした。

久々の日記&技術的な内容で、訳すのに手こずってしまいました( ´Д`)
また、技術的な事は私には今ひとつわかりませんので、内容が100%正しいかは保証できません。ご了承くださいm(_ _)m

とりあえず、DirectX11対応になってステラリスが部分的に高速化すると考えておけばよさそうですね。
なんにせよゲームが早くなるのは嬉しいことです(・∀・)

ステラリスがリリースされた2016年の前半頃ってPCゲーム=シングルスレッドのクロック数が高いものが圧倒的に有利という時代でintel製CPUがまだブイブイ言わせてた最後に近い頃だと思います。
確かその頃CPUコアをよりマルチ化したほうが有利ってのはウォッチドッグス2ぐらいじゃなかったでしょうか…。
そこから僅か数年でAMDのRyzenによって一気にCPUの他コア化が進んでPCゲームの処理も徐々に変わっていくんですよね。

そんなシングルコアの周波数が大正義の時代にステラリスは作られているので、今回の改良ってかなり大変だったかと思われます。開発チームに感謝ですね(-人-)

なお、本文最後で唐突にJeffさんって名前が出てきてましたが
パラドフォーラムの1コメントでジェフって誰だよ?ってツッコまれてたのが個人的にツボにはまりました(^_^;)

今回は以上ですm(_ _)m


Stellaris PS4版がリリース