Bullet2.86は対応途中で2.87から対応するようです。Githubから開発中の2.87を取得してマルチスレッド対応について調べてみました。結論から言えば、ゲームプログラムでは使えそうにありません。できるだけマルチスレッドに有利な状況を作っても、それほど処理時間は短縮されませんでした。大量のオブジェクトを扱う3DCGレンダリングなどで効果を発揮するかもしれません。
検証は4コアCPU(AMD A8-7650k)で行いました。CPUの種類、メーカー、PC環境で結果が大きく変わる可能性があります。また、使い方が間違っているだけかもしれません。
Bullet2.87
http://bulletphysics.org/
現在開発中、https://github.com/bulletphysics/bullet3よりダウンロードできます。ここからの説明は、2017年6月25日時点のバージョンに基づいています。内容が変わる可能性があるので注意してください。
検証用のサンプルプログラムを実行するだけであれば、2.87のダウンロードと構築作業は不要です。サンプルプログラムに必要なソースコードとプロジェクトを同梱しています。
VisualStudio用プロジェクトの作成は2.86と同じくCMakeかpremakeで行います。ゲームプログラムでの使用を想定しているため、VRやPythonなしfloat型を使用する
build_visual_studio_without_pybullet_vr.bat
でプロジェクトを作成しました。
マルチスレッドデモの実行
生成されたプロジェクト0_Bullet3Solution.slnをそのままビルド、実行ではマルチスレッドデモは実行できません。マルチスレッドデモを有効にするには、全プロジェクトのプリプロセッサ定義に
BT_USE_PPL=1;BT_THREADSAFE=1;
を追加します。BT_USE_PPLはVS2010から利用できる並列処理用のライブラリ(並列パターン ライブラリ)を有効にするための定義です。
また開発中のためかbtTaskScheduler.h/cppというソースコードが追加されていません。examples/MultiThreadingフォルダにあるのでデモプログラムのプロジェクトに追加してください。
ビルド、実行するとデモプログラムが起動、左のメニュー「Experiment/Multithreaded Demo」をダブルクリックするとマルチスレッドデモが実行されます。
Bullet2.87でのマルチスレッド処理
Bulletでは、Forループ処理をマルチスレッドで実行する仕様になっています。全体的にタスクやジョブ管理を行うのではなく部分的なマルチスレッド対応のようです。ForループをOpenMP、PPL(並列パターン ライブラリ)、TBB(Intel Threading Building Blocks)などを使用して高速化しています。
部分的な対応のためループ数が多くないと効果が薄いようです。
デモプログラムは、衝突の可能性がある剛体のグループ(アイランド)を多く、同じ形状のコリジョンを衝突させるなどループ数が多くなるように調整しているため、4コアCPUで実行すると50~60%時間が短縮されます。検証のために複数の異なる形状の剛体をランダムに重ねて配置した場合、ほとんど効果がありませんでした。
マルチスレッド処理の処理時間測定
デモプログラムを参考に検証プログラムを作成しました。スレッド処理にはPPLを使用、剛体をランダムに配置してBulletのシミュレーションstepの処理時間を計測しました。使用した剛体は、球、Box、円柱、円錐、カプセルをランダムに3000個、スレッド数は4、CPUはAMD A8-7650k(4コア)。
剛体を近い場所にランダム配置
アイランド数を少なく、形状もランダムにして衝突ペアの計算を複雑にした場合
アイランド数 | 2 |
スレッドON | 約85ms |
スレッドOFF | 約85ms |
ほとんど変わりませんでした。
剛体をグループ分け ランダム配置
アイランドが多くなるように分散して配置、形状はランダムに
アイランド数 | 25 |
スレッドON | 約44ms |
スレッドOFF | 約56ms |
約20%改善、スレッドを4つ使った割には効果が薄い気がします。ゲームプログラムでは他にもスレッドが必要になるので使わないほうが良いかもしれません。
剛体をグループ分け Box形状のみ
アイランドが多くなるように分散して配置、同一形状のため衝突ペアの処理が1種類
アイランド数 | 26 |
スレッドON | 約24ms |
スレッドOFF | 約37ms |
約35%改善、それなりに改善されますが条件が限定されすぎです。
結論
今のところゲームプログラムでの使用は難しいです。他の処理でスレッドを使用して高速化する方向で考えたほうが良さそうです。期待していたほど効果がなく残念です。Bullet2での大幅な変更はないと思われるため、Bullet3に期待です。
映像用3DCGツールで使用する場合、レンダリング時間の短縮になるかもしれません。時間がかかるため、数%の高速化であっても十分効果があります。コア数を増やせばもっと速くなるかも。
サンプルプログラム
Bulletマルチスレッド検証プログラムです。
必要なBulleのソースコードとプロジェクトを同梱、Bulletのダウンロードと環境構築は不要です。
“DirectX11 Bullet Physics 2.87 Multi-Thread” をダウンロード Bullet287Thread.zip – 234 回のダウンロード – 1 MB