【解決済み】並列処理の重さについて

アバター
にいやん
記事: 218
登録日時: 2016年7月02日(土) 00:38
お住まい: 地獄4丁目西のゴミ置き場
連絡を取る:

【解決済み】並列処理の重さについて

投稿記事by にいやん » 2017年9月03日(日) 22:56

並列処理の重さについてなのですが

A.普通にトリガーを並列処理にしたとき
B.ラベルジャンプで処理したとき
C.ループで処理したとき
※スタート位置を揃えるために条件は全て並列処理です。

新規キャンバス.jpg
新規キャンバス.jpg (95.63 KiB) 閲覧数: 3730 回


Cは言うまでもなく処理が重すぎて論外ですが、AとBの内部処理に違いはあるのでしょうか?
並列処理の場合は一番下まで処理が終わると一番上まで戻って繰り返すのですが、ラベルジャンプも同じ仕様なのでしょうか?並列処理の使い方次第で重くなったりならなかったりというのは聞いたことがあるのですが、内部処理での重さが蓄積するようなら並列処理をたくさん使う場合は出来るだけ軽い方が良いと思いましたのでAとBどちらが良いのか分かる方教えてください。

実際にゲーム内で使っている並列処理の数は10個程度ですがBの場合もあればAの場合のように垂れ流しの場合もあります。並列処理を使っていて重いと感じた事はありませんが今後、並列処理が多くなってしまったときに出来るだけ最善の方法を今のうちから作り上げたいと思っています。

Cのループ内にウェイトを1フレーム入れるとA.Bと全く同じスピードになりました。ということは並列処理で下から上に戻るときとラベルジャンプで特定の位置に戻るときは自動でウェイトが1フレーム入っているという認識でよろしいのでしょうか?そうなるとCはますます論外ですが…と言うよりループイベントのの霊圧が消えてしまうような…
最後に編集したユーザー にいやん on 2019年5月12日(日) 23:39 [ 編集 1 回目 ]

よしだとものり
記事: 134
登録日時: 2017年7月25日(火) 23:18

Re: 並列処理の重さについて

投稿記事by よしだとものり » 2017年9月04日(月) 00:46

ツクール(HTML5)がどうなってるのかは分からないですが
A、Bは自分が知ってる限りでは全て機械語の命令
+は加算、ラベルジャンプがどうか知らないけどジャンプも
機械語にある

自分が重いと感じるのはデカいマップと演出(霧とか)なんで
マップを小刻みにするとかなるべく派手な演出を控えたりしては
いかがかと。

とあるゲームで一番参ったのがダンジョンの霧の演出で
あまりの重さに積みゲーになりました。
アバター
トリアコンタン
記事: 2121
登録日時: 2015年11月10日(火) 21:13
お住まい: きのこ王国
連絡を取る:

Re: 並列処理の重さについて

投稿記事by トリアコンタン » 2017年9月04日(月) 03:09

こんばんは!

まずCのパターンですが、処理が重くなると言うより実質的な無限ループになっています。
なので、Cにウェイト1フレームを入れたものとを比較します。

並列処理の重さとは、「1フレームあたりに処理されるイベントコマンドの量」(もちろん単純な数ではなくコマンドによって重さには違いがあります)で決まります。

Aの場合
1フレーム中で実行されるのは「変数の操作」のみです。

Bの場合
1フレーム中に実行されるのは「ラベル」「変数の操作」「ラベルジャンプ」です。

Cの場合
1フレーム中で実行されるのは以下の通りです。
初回フレーム「ループ」「変数の操作」「ウェイト」
2フレーム目以降「以上繰り返し」「変数の操作」「ウェイト」

イベントコマンド「ウェイト」は少し特殊で、同一フレーム内でのイベント実行を一旦中断して、次フレームで処理を再開します。イベントコマンド「ウェイト」を処理の最後に入れると負荷が分散して軽くなるのはこの仕様のためです。
「ラベルジャンプ」も同様の仕組みを持っています。

本題のA,B,Cのどれが重いかですが、前提としていずれも体感で分かるような違いはありません。

それでも比較した場合、一見Aがシンプルで軽いように思いますが、毎フレームGame_Interpreterのオブジェクトを再生成するのでおそらくこの中では一番重いと思います。

BとCはほぼ同じ仕組みですが、「以上繰り返し」と「ラベルジャンプ」とでは僅かに前者の方が軽いと思います。
参考までに双方のコードを記載します。

以上繰り返し

コード: 全て選択

Game_Interpreter.prototype.command413 = function() {
    do {
        this._index--;
    } while (this.currentCommand().indent !== this._indent);
    return true;
};


ラベルジャンプ

コード: 全て選択

Game_Interpreter.prototype.command119 = function() {
    var labelName = this._params[0];
    for (var i = 0; i < this._list.length; i++) {
        var command = this._list[i];
        if (command.code === 118 && command.parameters[0] === labelName) {
            this.jumpTo(i);
            return;
        }
    }
    return true;
};

Game_Interpreter.prototype.jumpTo = function(index) {
    var lastIndex = this._index;
    var startIndex = Math.min(index, lastIndex);
    var endIndex = Math.max(index, lastIndex);
    var indent = this._indent;
    for (var i = startIndex; i <= endIndex; i++) {
        var newIndent = this._list[i].indent;
        if (newIndent !== indent) {
            this._branch[indent] = null;
            indent = newIndent;
        }
    }
    this._index = index;
};
プラグイン関連のトラブルが発生した際の切り分けと報告の方法です。
http://qiita.com/triacontane/items/2e227e5b5ce9503a2c30

[Blog] : http://triacontane.blogspot.jp/
[Twitter]: https://twitter.com/triacontane/
[GitHub] : https://github.com/triacontane/
アバター
にいやん
記事: 218
登録日時: 2016年7月02日(土) 00:38
お住まい: 地獄4丁目西のゴミ置き場
連絡を取る:

Re: 並列処理の重さについて

投稿記事by にいやん » 2017年9月04日(月) 08:35

よしだとものりさん、トリアコンタンさん、返信ありがとうございます。
体感で分かるような違いは無いということなので一安心しています。

もう一つ聞きたいのですが例えば並列処理の中でスイッチや変数を操作する場面があるのですが、スイッチや変数に変更があった場合、マップ上ではそこに存在するイベントの出現条件など、要するにスイッチや変数が関わる判定が入ると思うのですがスイッチや変数に変更がある場合とない場合で処理の重さに違いは出てくるのでしょうか?

わかりやすく説明しますと
並列処理の中で変数に1を代入する命令がある場合、代入するごとにマップでの他イベントの判定が行われるのかということです。スイッチや変数の値が変わらなければ参照するだけで他のイベントの判定が行われないというのであればそれだけで負荷分散になりそうな気もするのですがツクールの内部処理ではどのような感じになっているのでしょうか?

疑問に思っているのは太文字の部分です。
アバター
トリアコンタン
記事: 2121
登録日時: 2015年11月10日(火) 21:13
お住まい: きのこ王国
連絡を取る:

Re: 並列処理の重さについて

投稿記事by トリアコンタン » 2017年9月04日(月) 21:08

ご指摘の通り「変数の操作」「スイッチの操作」「セルフスイッチの操作」の命令が一度でも行われると、そのフレームで「リフレッシュ」処理が発生し、全マップイベントのページを再設定します。

この際、変数やスイッチの値が変化したかどうかは見ていません。1を代入し続ける場合でも毎回、リフレッシュ処理が発生します。

ただし、1フレーム中に「変数の操作」命令が2つ以上実行された場合でも、リフレッシュ処理が実行されるのは1フレームにつき一度だけです。ここが少し分かりにくいですが、うまく伝わりましたら幸いです。
プラグイン関連のトラブルが発生した際の切り分けと報告の方法です。
http://qiita.com/triacontane/items/2e227e5b5ce9503a2c30

[Blog] : http://triacontane.blogspot.jp/
[Twitter]: https://twitter.com/triacontane/
[GitHub] : https://github.com/triacontane/
アバター
にいやん
記事: 218
登録日時: 2016年7月02日(土) 00:38
お住まい: 地獄4丁目西のゴミ置き場
連絡を取る:

Re: 並列処理の重さについて

投稿記事by にいやん » 2017年9月04日(月) 22:06

トリアコンタン さんが書きました:変数やスイッチの値が変化したかどうかは見ていません。1を代入し続ける場合でも毎回、リフレッシュ処理が発生します。

ただし、1フレーム中に「変数の操作」命令が2つ以上実行された場合でも、リフレッシュ処理が実行されるのは1フレームにつき一度だけです。


とても参考になりました。並列処理を使う場合は、いままで以上に気をつけていこうと思います。どうもありがとうございました。
zen5656
記事: 25
登録日時: 2016年11月04日(金) 01:43

Re: 並列処理の重さについて

投稿記事by zen5656 » 2017年9月05日(火) 19:49

こんばんは。

自分にとっても良い勉強になるトピックありがとうございます。
他の方が書かれた内容で申し訳ないのですが、この記事ももしかしたら参考になるかもしれませんよ。

並列処理でスイッチや変数を操作すると重くなる【ツクールMV】
https://paradre.com/%E4%B8%A6%E5%88%97% ... A%E3%82%8B

“MV:質問” へ戻る