« 2018年5月 | トップページ

2018年7月の記事

2018年7月15日 (日)

「無限ループが発生してもハングアップしません」

最近、Unreal Engine の勉強を(少しだけ)していて、今日は「UE4 ブループリント超入門編」を読んだ。今までブループリントというのは、ゲームに必要になる典型的な処理だけをビジュアルにプログラムできるシステムだと思っていたので、基本機能が一通りそろっていて万能なのだという話は目からうろこだった。

それはともかく、この記事の最後の方にこう書いてある。

ちなみにブループリントは優秀なことに無限ループが発生してもなんとハングアップしません。かわりに無限ループが発生したと判断すればエラーになってエディターに戻ってきますので、安心して実行できますのでご安心ください。

ぱっと見、「止まらないコードはすべて検出してエラーにする」と言っているように見えるが、ブループリントが万能である以上、もちろんそんなことは不可能だ。そこで、実際に無限ループするブループリントを作って試してみた。いや、停止問題とかそういう高級なヤツじゃなくて、ばかみたいなやつ。

Infiniteloop

元記事にならって疑似コードで書けばこんな感じだ。

EventBeginPlay()
{
    while (true)
    {
        PrintString("Iterating...");
    }
    PrintString("Done.");
}

これをコンパイルすると…コンパイルできてしまう。VisualStudioだってコンパイル時にエラーを出す(「無限ループ」とは言わず、「while の後ろの PrintString に至るコードパスが存在しない」とかなんとか言うんだったと思うが)くらいの単純な例なのだが。コンパイルできたので動かしてみると、一瞬画面いっぱいにIterating...が並んで、エラーで止まった。Infinite Loop detected と言っている。なるほど、確かに実行時検出はできているようだ。だが停止問題は実行時にも検出できないはずだし、そもそも1周目では検出できないのに何周か動いたところで検出できるというのも奇妙だ。どういう風に検出しているのだろうか。いろいろ調べたところ、どうやらブループリントでは、「コードの同じ個所を100万回実行したら無限ループとみなして止める」という感じのことをやっているらしい。

なるほど。それならできる。お手軽でナンチャッテ的な手法だが、1フレーム時間(約17ms)を超えて動き続けるコードが(「無限」ループであろうとなかろうと)許されないゲームのスクリプトとしては、非常に実用的なデバッグ法なのだろう。これもまた目からうろこだった。

« 2018年5月 | トップページ