トップページ > 記事閲覧
ダメ出し希望(どなたでも)
名前:名無三 日時: 2019/12/31 22:55

戦車シミュを作成中です drive.google.com/file/d/1J5-9N5qz5i67JxGRiYmNY7Vz0hfwQCwr/view?usp=sharing 現在処理時間の短縮化を目指しています。0.5~1ms程度の高速化には成功しましたが、いまだ10~15ms程度時間がかかってしまいます。 そこで、厚かましいとは思いますが「ここなんでこんな書き方なの」「こんな技法あるからggr」のような感じでアドバイスをお願いしたいです。 *1ms以上時間がかかってしまっている部分として、 ・視点を移動している時のスカイボックス描画部分(1.6ms) ・CPUが射線を通せているか判定する部分(0.1~4.5ms) ・地面に沿わせる判定、弾の当たり判定部分(5.3ms) ・エフェクシアの再生処理部分(0.8~1.2ms) が見当たります(手前での高速化済の値です)
メンテ

Page: 1 |

Re: ダメ出し希望(どなたでも) ( No.1 )
名前:管理人 日時:2020/01/01 06:24

とりあえずビルドして実行しながらどこが重そうか確認しようと思ったのですが、 ビルドできる環境を揃えるのに手こずっています… よろしければ Effekseer や Box2D など、ビルドに必要なミドルウェアなどの 揃え方を教えていただけないでしょうか? m(_ _;m
メンテ
Re: ダメ出し希望(どなたでも) ( No.2 )
名前:名無三 日時:2020/01/01 12:20

失礼しました、こちらをCドラ直下に置いています drive.google.com/file/d/1m9WA8JYiNdAQHObtyvHY_E9Pv8FKdOtE/view?usp=sharing (念のため) Box2Dのビルドはこちら github.com/erincatto/Box2D dxlib.xsrv.jp/cgi/patiobbs/patio.cgi?mode=view&no=4774 (方法) エフェクシアはこちらから effekseer.github.io/jp/download.html
メンテ
Re: ダメ出し希望(どなたでも) ( No.3 )
名前:yumetodo 日時:2020/01/02 02:12

void quick_sort(sorts sort[], int left, int right) STLのstd::sortに任せましょう。 cpprefjp.github.io/reference/algorithm/sort.html const char* getstr(const char * p1, int p2, const char * p3) { std::string tempname = p1 + std::to_string(p2) + p3; return tempname.c_str(); } const char* getstr_2(const char* p1, std::string p2, const char* p3) { std::string tempname = p1 + p2 + p3; return tempname.c_str(); } だめです。tempnameは関数を抜けた時点で生きてません。UBです。 他にもたくさんありますがとりあえず寝るのでここまで
メンテ
Re: ダメ出し希望(どなたでも) ( No.4 )
名前:管理人 日時:2020/01/02 06:09

ありがとうございます、手元で実行できました 負荷表示2が常に 5msくらいなのも気になりますが、 敵に近づいたときに負荷表示1が 13msくらいに跳ね上がるのも気になります… デバッグビルドで詳しく確認してみたいと思い Debug x64 にビルドターゲットを変更して 実行してみたのですが、define.cpp の 133行目でエラーになってしまいました ( vecs[j].frames が -1 になっているのが原因のようです ) デバッグビルドでも実行できるようにしていただくことは可能でしょうか?
メンテ
Re: ダメ出し希望(どなたでも) ( No.5 )
名前:名無三 日時:2020/01/02 06:38

yumetodoさん、box2Dのほうの情報含めありがとうございます! ソートのほうは応急措置のような形ですが工事完了しました… UBを未定義動作である等初めて知りC++の深さに驚愕している次第ですが、こちらのほうはどう改善すべきでしょうか… 思いついたのは ・いったんcharの一時変数を作ってそれを返す->固定長になるしnewできてもdeleteできんやろ ・この関数やめる->そもそもHSP時代にやってた3以上の文字列や数字をまとめられる書き方が恋しくてやってんだからどうにかするんだよ! ( named = "コブラ" dim fnk fnk=765 name = "data/"+fnk+"/idol/"+named+".data" mes name みたいな感じ ) といった感じで案が一向に思い浮かばず... 関数を std::string getstr(); としてDXLIBにはgetstr().c_str()と渡すというのが思いついた中で一番まともかなと思うのですが、これでいいのでしょうか… 管理人さん、またご迷惑をおかけして申し訳ありません… 実のところかなり以前からデバッグ時の実行が不可能でありまして、原因も定かでないまま開発を続けてしまっております。 デバッグ時を動作環境にできるかは不透明ですが、なんとかやってみます 追記:敵に近づいたのは敵との距離が500以内に近づいた時でしょうか? そちらについては地形の当たり判定のもつバウンディングボックスが複数該当するほど長い線分をもとにしてしまうからと仮定しています。
メンテ
Re: ダメ出し希望(どなたでも) ( No.6 )
名前:名無三 日時:2020/01/02 14:27

修正しました、STL強いっすね… drive.google.com/file/d/1BzJnyWGiKhv7Uvc7Q119Yzi1qnauxTf0/view?usp=sharing debug動作も確認できました
メンテ
Re: ダメ出し希望(どなたでも) ( No.7 )
名前:yumetodo 日時:2020/01/03 00:29

とりあえず高速化の前に安全ではない部分や書き方を直していこうと github.com/yumetodo/TankFlanker/pull/1 を作っています。差分を確認してみてください。 Githubのアカウントをお持ちでしたらusername, full name or email addressを教えてきただければTransfer ownershipします 基本的な話ですが、C++においてnewやらmallocやらcallocやらするのは99%の確率で誤った用法です(placement newが唯一の例外)。 std::vectorやstd::string、それが適当でなければstd::unique_ptrやstd::shared_ptrを使ってください。 またRAIIの技法を使うとデストラクタでいろいろせずに済みます。上のURLでいうMV1Handleクラスが該当ですね。 サウンドやフォントについても同様のことが言えます。 そうするとデストラクタを書くのはRAIIの技法を実装するときとvirtualな関数を持つクラスの継承が絡む時を除いて常に誤りと言うことができます。
メンテ
Re: ダメ出し希望(どなたでも) ( No.8 )
名前:名無三 日時:2020/01/03 06:03

yumetodoさんありがとうございます! Github道程なので反映などほとんどわからない状態であることを承知願います、申し訳ございません emiya_ubw a6m3.zero.fあgmail.com とりあえずstd::vectorでnewでやっているところを置き換えていきます
メンテ
Re: ダメ出し希望(どなたでも) ( No.9 )
名前:管理人 日時:2020/01/03 07:14

デバッグビルドでも動作するバージョンのアップありがとうございます プログラムの書き方については yumetodoさんがご返答されているので 私は高速化に関連することを… 少し拝見した限りでは for (i = 0; i < player[p_cnt].ptr->colmeshes; ++i) { MV1RefreshCollInfo(player[p_cnt].colobj, -1, i); } こちらの行でかなりの処理時間を喰っているようです ビューアーで確認した限りでは colobj のコリジョン用モデルのポリゴンが多のが原因だと思います 例えば Pz_ausfIV_F2 の col.mv1 ではキャタピラの車輪の円が20頂点で表現されていますが これはもう6頂点くらいの粗い円で問題ないと思います 左右のキャタピラ部分だけで2560ポリゴンあるのは勿体ないと思います( 全体で3404ポリゴンなので、 殆どがキャタピラの車輪のような円の表現の部分にポリゴン数が割かれています ) コリジョン判定用の頂点の計算は全てCPUで行っていて、ポリゴン数の多さに比例してCPU負荷が 増加しますので、コリジョン用モデルはなるべくポリゴン数を減らすようにしてみてください > 追記:敵に近づいたのは敵との距離が500以内に近づいた時でしょうか? > そちらについては地形の当たり判定のもつバウンディングボックスが複数該当するほど長い線分をもとにしてしまうからと仮定しています。 どうやらそのようです こちらについてはDXライブラリ側で少し軽くすることができそうなので、ちょっと高速化を試してみます 少々お待ちください m(_ _)m
メンテ
Re: ダメ出し希望(どなたでも) ( No.10 )
名前:yumetodo 日時:2020/01/03 13:52

どうやらGitHubのアカウントが存在していないようです。作成途中で終わってるとか・・・?
メンテ
Re: ダメ出し希望(どなたでも) ( No.11 )
名前:名無三 日時:2020/01/04 06:59

あ、ごめんなさいユーザーネームを間違えていました。名前があれなので (見られ次第消します) --- drive.google.com/file/d/1u13IAZvQS4PIKchU8iBKUZowaPTkPBO3/view?usp=sharing とりあえずnew/del箇所をほぼつぶしました https://drive.google.com/file/d/1ixXKlsu24rAlAOjqWmJ5QC-PfLDzvFey/view?usp=sharing コリジョン用モデルを簡略化しました。1ms弱処理が短縮された模様です きちんと読み込まれているのか不明瞭なのですが、どうやらMV1LoadModelWithStrLenでの読み込みでは成功したハンドルが帰ってきているのですが描画等はすべて できない模様です…どうして…
メンテ
Re: ダメ出し希望(どなたでも) ( No.12 )
名前:yumetodo 日時:2020/01/04 01:48

さしあたってご提示のコードをmergeして、 ついでにこちらの変更ミスだったMyClass::set_fontsをC++17 fold式で書き直しました(CreateFontToHandle呼んでなかった)。 あととりあえずレポジトリに招待しましたので、 GitHubの通知からGitHubのアカウントに紐付いているメールアドレスの受信トレイを確認して招待を受けてください。
メンテ
Re: ダメ出し希望(どなたでも) ( No.13 )
名前:管理人 日時:2020/01/04 06:22

> コリジョン用モデルを簡略化しました。1ms弱処理が短縮された模様です 私の手元では for (i = 0; i < player[p_cnt].ptr->colmeshes; ++i) { MV1RefreshCollInfo(player[p_cnt].colobj, -1, i); } の処理時間が 1.8ms から 1.3ms に短縮されたのですが、ポリゴン数が約半減しているのに 短縮の度合いが少ないと思い確認したところ… すみません、処理時間に大きく影響するのはポリゴン数ではなく頂点数でした m(_ _;m ポリゴン数は以下の通り半分近く減っていますが Pz_ausfIV_F2 旧 3404  新 1726 Pz38(t)    旧 1281  新 1105 T-34-85    旧 3356  新 1896 頂点数はそれほど減っていなかったり、寧ろ Pz_ausfIV_F2 以外は増えてしまっていました Pz_ausfIV_F2 旧 3664  新 2470 Pz38(t)    旧 1490  新 1566 T-34-85    旧 3100  新 4082 Pz_ausfIV_F2 が最も多く表示されているので頂点の合計数では減っているため処理時間が若干短縮された、 ということのようです Pz_ausfIV_F2 表示数 11 Pz38(t)    表示数 1 T-34-85    表示数 4 頂点の総数 旧 54194  新 45064 頂点数が増えてしまった原因について何か思い当たる点などありますでしょうか? あと、DxLibModelViewer でフレームを選択した際に、フレームに含まれるメッシュの頂点数も表示するように処理を 変更してみましたので、よろしければ頂点数をご確認の際にこちらをお使いください m(_ _)m // ビューアー https://dxlib.xsrv.jp/temp/DxLibModelViewerTest.zip > きちんと読み込まれているのか不明瞭なのですが、どうやらMV1LoadModelWithStrLenでの読み込みでは成功したハンドルが帰ってきているのですが描画等はすべて > できない模様です…どうして… SetUseASyncLoadFlag( TRUE ); を実行して非同期読み込み設定の状態でしたら、仮にファイルパスが誤っていても MV1LoadModelWidhStrLen は有効なハンドルを返してきます SetUseASyncLoadFlag( FALSE ); の状態で MV1LoadModelWidhStrLen で読み込もうとしても成功しますでしょうか?
メンテ
Re: ダメ出し希望(どなたでも) ( No.14 )
名前:管理人 日時:2020/01/05 07:12

No.9 で申し上げていた『敵に近づくと処理負荷が高くなる』の原因となっていた MV1Collision_Line を 高速化する作業が完了しましたので、よろしければこちらをダウンロードしてください m(_ _)m https://dxlib.xsrv.jp/temp/DxLibVCTest.zip // Windows版 VisualC++ 用 https://dxlib.xsrv.jp/temp/DxLibBCCTest.zip // Windows版 BorlandC++ 用 https://dxlib.xsrv.jp/temp/DxLibBCC2Test.zip // Windows版 C++ Builder 10.3 用 https://dxlib.xsrv.jp/temp/DxLibGCC_MinGWTest.zip // Windows版 MinGW 用 https://dxlib.xsrv.jp/temp/DxLibDotNet.zip // Windows版 .NET用 https://dxlib.xsrv.jp/temp/DxLibMakeTest.zip // ソース (中身を既存のライブラリのファイルに上書きして『リビルド』をして下さい) 手元で試した限りでは敵に近づいても負荷表示1の数値が跳ね上がることはなくなりましたので それなりに効果があると思います
メンテ
Re: ダメ出し希望(どなたでも) ( No.15 )
名前:名無三 日時:2020/01/05 07:29

ありがとうございます 昨日おぼほぼPC触れずで何もアクション返せずですいません drive.google.com/file/d/1P42zMM3nZAsHcZY5m7gnfhv9hnqtGOq7/view?usp=sharing どうやらメタセコの頂点表示が誤っているように思います、戦車らの頂点を修正しました
メンテ
Re: ダメ出し希望(どなたでも) ( No.16 )
名前:yumetodo 日時:2020/01/05 09:48

ところで inline void* b2Fixture::GetUserData() const { return m_userData; } inline void b2Fixture::SetUserData(void* data) { m_userData = data; } って何をしている関数なのでしょう? player[p_cnt].playerfix->SetUserData(NULL); delete player[p_cnt].playerfix->GetUserData(); のそれぞれ1箇所でしか呼ばれていないわけですが
メンテ
Re: ダメ出し希望(どなたでも) ( No.17 )
名前:名無三 日時:2020/01/05 17:28

box2Dのサンプルそのまんま導入したので実際のところわかりかねます… 500m以内での処理落ち改善確認できました、ありがとうございます GitHubのコミットのほうこれでいいんでしょうか…
メンテ
Re: ダメ出し希望(どなたでも) ( No.18 )
名前:管理人 日時:2020/01/06 01:38

頂点修正版を拝見しました、DxLibModelViewer でも以下の通り頂点が減っているのを確認できました Pz_ausfIV_F2 旧 3664  新 2470 Pz38(t)    旧 1490  新 1113 T-34-85    旧 3100  新 2001 処理負荷   旧 1.8ms  新 1.2ms ただ、まだ若干頂点数が多いように感じます 当たり判定用モデルは画面に表示されることはありませんので、当たり判定に支障のない範囲で ゴリゴリ形を単純化してしまっても問題ありません 処理負荷1.2msはほぼ頂点数と比例していますので、処理負荷をさらに下げたい、と思われた際は 更なる頂点数削減を検討してみてください あと、毎フレーム MV1RefreshCollInfo を全てのコリジョンモデルに対して行われていますが、 当たり判定に支障が無ければ以下のように毎フレーム 0 と 1 を繰り返すカウンタを用意して カウンタが 0 の時は偶数番号のコリジョンモデルを更新して、カウンタが 1 のときは 奇数番号のコリジョンモデルを更新するようにすることで、MV1RefreshCollInfo の1フレーム辺りの CPU負荷を半分に減らすことができます int RefreshCounter = 0; // 初期化はメインループ外で // メインループ while( ProcessMessage() == 0 ) { for (p_cnt = 0; p_cnt < playerc; ++p_cnt) { if (p_cnt % 2 == RefreshCounter) { // カウンタが1の時は奇数番号だけ、0の時は偶数番号だけ if の中に入る for (i = 0; i < player[p_cnt].ptr->colmeshes; ++i) { MV1RefreshCollInfo(player[p_cnt].colobj, -1, i); } } } RefreshCounter = RefreshCounter == 0 ? 1 : 0; // 毎フレームカウンタを 0 と 1 で繰り返す } ( もし1フレーム(1/60秒)で移動する距離が長く、当たり判定処理に支障が発生する場合はこの 方法は使用できませんが… ) 処理負荷に関して私から申し上げられることは以上となります ( プログラムの書き方については yumetodoさんにお任せ… ) 極端に処理負荷が高い部分については改善できたと思うのですが、 名無三さん的に他にも『この部分が何故か異常に負荷が高い』という部分や 『ここをもっと軽くできないだろうか?』という部分ははありますでしょうか?
メンテ
Re: ダメ出し希望(どなたでも) ( No.19 )
名前:名無三(軽量化解決) 日時:2020/01/06 21:51

今のところ気になる部分はありません、ご協力に感謝します!
メンテ
Re: ダメ出し希望(どなたでも) ( No.20 )
名前:yumetodo 日時:2020/01/07 16:49

とりあえず概ね安全性も向上したので、あとは/W4で出ている警告(C6289、C26495、C26451)に対処してもらえばいいんじゃないかなって思ってます。 他に速度を下げているようなところもさして見当たらないのでまあいいのではないかなと。
メンテ

Page: 1 |

題名
名前
コメント
パスワード (記事メンテ時に使用)

   クッキー保存