テクノロジー : ゲーム開発者の憶測の検証

ARTICLE BY:
POSTED:

TAGS:

ゲーム開発者は、コンパイラの動作方法について、数多くの憶測を立てます。SN Systems では、テストツールである「Check CFC (Compile Flow Consistency)」を実装し、PlayStation®4 (PS4) のコンパイラでも、憶測が正しいことを確認するお手伝いをしています。「Check CFC」は、オープンソースの LLVM コンパイラコミュニティで共有されています。

中間アセンブリ ファイルの使用

憶測:

「オブジェクトファイルに直接コンパイルするのは、アセンブリファイルに
コンパイルしてからアセンブリを行うのと同じである」

ゲーム開発の細かい作業では、アセンブリファイルがしばしば利用されます。例1のコードは、中間アセンブリファイルを使用した場合に生じた問題を示しています。「Check CFC」ツールを使えば、コンパイラがオブジェクトファイルに直接コンパイルを行った際、コンパイラが長い命令のエンコーディングを使用したことがわかりますが、中間アセンブリファイルを使用した場合にはより短くかつより効果的なエンコーディングが生成されたことが分かります。たいしたことではないのでは、と思われるかもしれませんが、余分なコードは挙動に影響を与えますので、ゲームパフォーマンスにおいては、その違いが大きくなることがあります。

int foo(int a)
{
   return ++a;
}

例 1:ソースコード

$ clang -c increment.c
Check CFC, checking: dash­_s_no_change
Code difference detected with -S
--- /tmp/tmpusdb4b.o
+++ /tmp/tmprdm_gk.o
@@ -6,6 +6,6 @@
 0000000000000000 <foo>:
    0:  89 7c 24 fc             mov    %edi,-0x4(%rsp)
    4:  8b 7c 24 fc             mov    -0x4(%rsp),%edi
-   8:  81 c7 01 00 00 00       add    $0x1,%edi
-   e:  89 7c 24 fc             mov    %edi,-0x4(%rsp)
-  12:  89 f8                   mov    %edi,%eax
+   8:  83 c7 01                add    $0x1,%edi
+   b:  89 7c 24 fc             mov    %edi,-0x4(%rsp)
+   f:  89 f8                   mov    %edi,%eax
*** Diff truncated ***

例 1:Check CFCテストツールからの出力

デバッグ情報の生成

憶測:

「デバッグ情報の生成に際しては、生成されたコードにおける副作用はない」

ゲーム開発者は、リリースするコードとまったく同じコードをデバッグする必要があります。例2からは、「–g」(デバッグ) オプションを使用してコンパイルしたものと、これを使用しないでコンパイルしたもので、生成されたマシンコード内に違いがあることが分かります。「–g」が有効化されると、コンパイラによってmov命令が削除されます。ここでも、違いは取るに足りないものと思われるかもしれませんが、こういった小さな問題がゲームコード内のデバッグ問題に発展すると、開発者にとっては頭痛の種となります。

struct Foo
{
  bool bar();
  bool operator==(Foo &baz) { return (this == &baz); }
};
Foo *wibble;
bool Foo::bar() { return (*this == *wibble); }
int main() {}

例 2:ソースコード

$ clang -c -O2 test.cpp
Check CFC, checking: dash_g_no_change
Code difference detected with -g
--- /tmp/tmpk4rtvb.o
+++ /tmp/tmpc8erml.o
@@ -5,6 +5,6 @@
 0000000000000000 <_ZN3Foo3barEv>:
    0:  48 8b 05 00 00 00 00    mov    0x0(%rip),%rax
-   7:  48 39 38                cmp    %rdi,(%rax)
-   a:  0f 94 c0                sete   %al
-   d:  c3                      retq
+   7:  48 8b 00                mov    (%rax),%rax
+   a:  48 39 f8                cmp    %rdi,%rax
+   d:  0f 94 c0                sete   %al
*** Diff truncated ***

例 2:Check CFCテストツールからの出力

「Check CFC」 – Compile Flow Consistencyのテスト

SN Systemsが開発した「Check CFC」ツールを使うと、上記のような問題を検出することができます。「Check CFC」は、コンパイラのふりをするため、同一のマシンコードの生成が期待される複数の方法で「本物の」コンパイラを実行します。「Check CFC」は、次にそれぞれのオブジェクトファイル内に生成されたコードが同一であるかどうかをチェックします。差異が検出された場合には、影響のあったマシンコードが表示されるため、不具合の発見がより簡単になります。

この2つの例は、「Check CFC」を使用しLLVMコンパイラ内で発見された現実にあった不具合で、発見後はLLVMのオープンソースコミュニティにより迅速に修正されました。

まとめ

PS4コンパイラはLLVMのプロジェクトをベースとしています。SN Systemsはオープンソースコミュニティにいる数百人のエンジニアと世界規模で連動し、コンパイラの質を向上させています。ゲームコードは他の各種ソフトウェアと比較するとユニークな特性があるため、ゲーム開発は他の各種ソフトウェアとは異なるワークフローで進められます。よって、当社では、コンパイラをテストするためのツールをゲーム開発に特化した方法で開発しています。

SN Systemsはこの「Check CFC」ツールをLLVMコンパイラプロジェクトに提供することでプロジェクトへの貢献を続けています。「Check CFC」ツールはここでご利用いただけます (http://llvm.org/svn/llvm-project/cfe/trunk/utils/check_cfc/)。このチェッカーをLLVMで共有することにより、上記例のような新しい不具合が発生した場合でも、コンパイラのユーザーが不具合を見つける前の、早い段階でのバグのキャプチャ・修正が可能になります。

トップに戻る