ニュース
[GDC 2012]x86版AndroidはARM版とここが違う。Intelがx86への対応方法を解説
そこでIntelがしなければならないのは何よりもまず,x86版Android環境に対応するためのアプリを用意してもらうこと。GDC 2012で同社は,ゲーム開発者に「x86に対応するAndroidアプリの作成法」を解説するという,かなり直球勝負のセッションを開いてきたので,その内容をまとめてみよう。
Android NDK採用ゲームアプリを
x86へ対応させるには
Androidのアプリでは,「Dalvik VM」と呼ばれる仮想マシンの上で動くJavaバイトコード――Javaのコンパイラが生成する中間コード。実行にあたってはVM内でネイティブコードに変換される――を用いるのが基本だ。仮想マシン上のJavaバイトコードは,x86やらARMやらといったCPUアーキテクチャとは関係なく互換性を持っている。
ただ,仮想マシン上で動作するJavaバイトコードは,(以前よりは高速化されているものの)複雑な3Dゲームを快適に実行できるほどでもない。そこでGoogleはDalvik VMとは別に,CPUのネイティブコードを使ってライブラリの開発を行える環境「Android NDK」(NDK:Native Development Kit)もリリースしている。そして現実的に,リッチなゲームタイトルの多くはこれを使って開発されている。
ここで重要なのは,「大多数のAndroid端末で採用されているCPU」,つまりARMアーキテクチャのCPUネイティブコードが使われているところ。要するに,ARM環境向けに作られたリッチなゲームは,x86 CPUコアを搭載したAndroid端末では動作しないのだ。これをなんとかしようというのが,本セッションのテーマである。
ただ,「Android NDKを使う」と言っても,多くのゲームで実際にはCやC++といった言語が使われている。そのため,「CやC++をCPUのバイナリコードへ翻訳するコンパイラ」にx86用を使えばx86用ライブラリができあがるはずで,ARM版Android用のゲームをx86版Androidへ移植するのはそう大変なことではない。セッションを担当したIntelのOrion Granatir氏が冒頭で最初に説明したのがこの点だ。
ただ,同じCやC++のソースコードを使うと,まれにx86環境で問題が生じることもある,とGranatir氏。最初の問題として取り上げられたのが,メモリ上におけるデータの並び方「アラインメント」(Alignment)の違いだった。x86だと並べ方にこれといった制限がなく,キャッシュ境界をまたぐと性能が低下するという問題がある程度なのだが,ARMは8bytesの境界をまたいでデータを並べたりしてはいけないCPUアーキテクチャになっている。
なので,ソースコード上では同じように並べたデータが,実際のメモリ上ではそうならないケースが生じ得る。Granatir氏は「通常は問題にならない」と述べつつ,たとえばストレージデバイス上においてARMのアラインメントで並んでいるデータをx86から読み出そうとしたときには問題になることがあるとも指摘していた。
もっとも,アラインメントの問題は割とよく知られている話。むしろGranatir氏が2つめの問題として挙げていた「メモリアクセス順の違い」のほうが,知らないでいると落とし穴になりそうな気配である。
x86ではメモリのリード/ライトがプログラムで指示された順番に従うと保証されているのに対し,ARMではそれがない。なので,2つのスレッドが同じフラグ(変数)を参照するときには,変数の変更順序がプログラムどおり行われない可能性を考慮して,組み込み関数で同期を取る必要があるというのが,ここでのポイントになる。
以上は一般的なCやC++コードにおける注意点だが,「NEONだけは移植するしかない」とGranatir氏が述べていたことも押さえておきたい。NEONはARMのマルチメディア命令セットで,x86におけるSSEのような拡張機能。よって,x86で動作させるには,SSEへ移植する必要が生じるのである。
ちなみにGranatir氏は「SSEはすべてのAtomプロセッサでサポートしているのに対し,ARMのNEONはオプション」と述べ,少し自慢げな顔をしていたが,ARMv7に対応した現行世代のARMコアはたいていがNEONをサポートしているので,氏がスライド中で指摘するほど,そこに大きな違いはないようにも思われた。
そのほかGranatir氏はコンパイラオプションについても触れ,「『-mfast-math』を付けると,ゲームでは少しよいコードになることが多い」といったアドバイスを行う一幕もあった。
氏はまた,SSE3の命令を自動的に出力する「-mssse3」にも触れていたが,Androidで使われているコンパイラ「GCC」の自動ベクタライズ――SSEのようなベクタ型の命令をコンパイラが自動で作ってくれる機能――はあまり大したものでもなかったりするので,「-mfast-math」と比べると効果は大きくなさそうだ。
Android端末側ではARMかx86かという
アーキテクチャを意識せずに利用できる
それほど大きく変更しなくていい部分と,移植しなければならない部分とがあるx86対応だが,いずれにせよ,Android NDKで作成されるライブラリは,ARM向けとx86向けで異なるファイルになる。
だが,APKには「FAT Binary」という仕組みがあり,複数アーキテクチャのバイナリを1つにまとめられると,Granatir氏は言う。
複数のバイナリを1つにまとめたAPKファイルは,Android端末へインストールするとき,CPUアーキテクチャに合うバイナリファイルだけが取り出される仕組みになっている。ただし,本セッションのサポートに入っていたGoogleのIan Lewis氏いわく「APKファイルの容量に注意して。データは2GBまで許容されても,コードは50MBまでという制限があるから」。APKファイルは圧縮されているため,ゲーム本体が50MBを超えるというのはなかなか現実的でないが,複数のアーキテクチャに向けて入れ込むと,たしかに制限超えの可能性はあるかもしれない。
以上,徹頭徹尾開発者向けに,小細工抜きでx86への対応方法を語るという内容だったわけだが,アプリをダウンロードする側に立つゲーマーが知っておくといいのは,ARM版Android向けのゲームがx86へ移植されるのには時間がかかる場合があることと,移植さえされてしまえば,ARMとx86の違いを意識する必要はなさそうだということである。
x86版のAndroidスマートフォンがいつ日本にやってくるのかは定かでないが,登場した暁には,今回のポイントを思い出すといいことがあるかもしれない。
Intelのスマートフォン製品公式Webページ(英語)
- 関連タイトル:
Atom
- この記事のURL:
(C)Intel Corporation