MacのCPUをインテルからApple Siliconに乗り換えることは、アップル自身にとってはもちろんのこと、サードパーティのアプリのデベロッパーにとっても、そしてユーザーにとっても、それなりに大事業であり、大きな変化を余儀なくされることがあるのも確かだ。
しかしアップルでは、この大事業をできるだけスムーズかつシームレスに成し遂げられるよう、そしてユーザーやデベロッパーの負担ができるだけ小さくて済むように、何種類、何段階もの施策を用意している。
WWDC20のキーノートでも述べられていたように、こうした動きを広く捉えると全部で4種類の方策が数えられる。そのうち最初の2つが特に重要だ。1つはインテルとApple Silicon、両方のネイティブコードを含む1つのアプリを提供するためのUniversal 2というバイナリフォーマットの採用。もう1つは従来のインテル用のアプリをApple Silicon Mac上で自動的に変換して実行できるようにするRosetta 2の導入だ。アップルでは、それらに加えてサードパーティ製の仮想化技術と、iPhone/iPadアプリがそのままMac上でネイティブ動作するBig Surの新しいアプリ環境を挙げている。
それに比べると、以前には存在しなかったiPhone/iPadアプリの動作環境は、インテルからApple Siliconへのスムーズ/シームレスな移行には直接関係ないように思えるかもしれない。しかし、Apple Siliconに移行した直後には、真にネイティブなサードパーティ製のMacアプリが不足気味になる可能性もあることを考えると、その際にネイティブで動作するiPhone/iPadアプリが存在するのは、ユーザーにとっても心強いことだと考えられる。
ともあれ、やはり今回の移行をストレスのないものにするための重要な技術は、Universal 2とRosetta 2の2つであることは間違いない。これらの技術は、主に誰のためにあるものかと考えると、対照的な位置づけであることに気付く。つまり、Universal 2は、アプリのデベロッパーが利用して、両方のCPUにネイティブ対応できるアプリを作成するためのものであるのに対して、Rosetta 2はもっぱらユーザーが利用して、旧形式のアプリを新しいプラットフォームで動作させるためのもの。それぞれ現時点でわかっている範囲で詳しく見ていこう。
デベロッパーのトランジションをスムーズにするUniversal 2
今回のWWDCで、Universal 2について最初に言及したのは、もちろんキーノートだった。その際には、インテル用とApple Silicon用のネイティブコードを1つのバイナリで供給できるフォーマットであることが紹介されただけで、それ以上の技術的なことは述べられなかった。
ただしデモとしては、すでにApple Siliconにネイティブ対応しているマイクロソフトやアドビなど、大手のデベロッパーのアプリが登場した。こうしたアプリは、インテルからApple Siliconへの移行期間として想定されている少なくとも2年間は、Universal 2アプリとして供給されることになるだろう。実のところユーザーの手元には、さらに長期間インテルMacも残るはずなので、Universal 2アプリが必要とされる期間は2年よりもう少し長くなるはずだ。
キーノート以外では「Platforms State of the Union」でも、実際にXcodeを使ってUniversal 2アプリをビルドするデモを交えなから、より詳しい話が語られた。
そこでまず出た話は、複数のCPU用コードを内蔵するユニバーサルアプリは、特に新しいものではないということ。Macでは、PowerPCからインテルに移行する際にはもちろん、同じインテルでも32ビットから64ビットに移行する際にも同様の仕組みを利用している。それを考えれば、今回は複数のCPUコードの組み合わせが、インテルとApple Siliconになったに過ぎないと考えることも可能だろう。
また、ユニバーサルアプリの基本的な情報として、コードは確かに2種類だが、それ以外のリソースはすべてひととおりしか持たないということも示された。つまり、画像や音声、3Dモデル、機械学習モデルといった容量が大きくなる可能性のあるデータは、コードの種類によらず共通なので、1つ持てばいい。そのため、ユニバーサルアプリにしてもアプリのサイズの増加は最小限に留められる。実際の増分はアプリの内容によって異なるが、通常のアプリでは純粋なコードの容量はアプリサイズの数十%以内だろう。とすれば、その部分だけが2倍になっても全体の増分は元の数十%に収まることになる。仮にリソースとしてのデータをまったく持たず、すべてコードだけで構成されているようなアプリがあったとしても、最大でほぼ2倍には収まるはずだ。
Xcodeでアプリをビルドする場合、そのXcodeが動作しているMacと同じアーキテクチャのネイティブコードをターゲットにビルドするには、単にそのMacの名前(この例では「My Mac」)を選べばいい。そして、Universal 2アプリをビルドするには、その選択を「Any Mac」に変更するだけ。それだけで、インテルとApple Silicon、2種類のCPUの実行コードを含んだユニバーサルアプリがビルドできる。
原理的には、このようにXcodeのターゲットを切り替えるだけでUniversal 2対応のアプリを作成できるわけだが、アップルではインテルアプリからUniversal 2への移行に要する時間を、ほとんどのデベロッパーについて「数日」以内としている。それは、CPUのアーキテクチャの違いからくる可能性のある問題を解決したり、最適化したりするのに時間を要する場合があるからだろう。
それでも、インテルからApple Siliconへの移行は、少なくともPowerPCからインテルへの移行よりは、かなり楽にできるはずだとしている。その理由として、3つの要因を挙げている。
まず、Apple Siliconとインテルのエンディアンが同一だから。つまり2バイト以上で表現するデータのメモリ上での配置の順番が、いずれも下位バイトのデータをメモリアドレスの小さいほうに、上位バイトのデータをアドレスの大きいほうに格納していくリトルエンディアンを採用している。そのため、データのバイト順をスワップする必要がない。
実はPowerPCは、バイエンディアンと言って、リトルエンディアンとビッグエンディアンのいずれに設定することも可能だった。しかしMacでは、それ以前の68Kプロセッサーがビッグエンディアンだったため、PowerPCをインテルとは逆のビッグエンディアンで使用していたのだ。PowerPCからインテルに変換したアプリでは、実行時にデータを扱うたびに余計な時間がかかるだけでなく、トリッキーなデータの扱いをしているプログラムでは、重大な、それでいて見つけにくいバグの原因となっていた。
2つ目の理由は、macOSアプリのデベロッパーは、iOS/iPadOSアプリもリリースしていることが多いことからくるもの。その場合、macOS用とiOS/iPadOS用のコードで、ソースレベルでは共通のものも少なくないはずだ。少なくともその部分は、すでにARMアーキテクチャへの移行が完全に済んでいることになる。そこには触る必要なくユニバーサルに移行できる。
3つ目は作業効率的な問題だが、Apple Silicon用アプリを開発するマシンは、必ずしもApple Silicon搭載Macである必要はない。つまりXcode 12をインストールしたインテルMacでも、Apple Silicon用のコードを含むUniversal 2アプリをクロスコンパイルしてビルドすることが可能なのだ。それによって、Mac用アプリのデベロッパーは既存のリソースをフルに生かしてApple Silicon対応アプリ開発に取り組むことができる。
なお「Port your Mac app to Apple Silicon」というセッションでは、アプリがCPUに関わるローレベルの情報を直接扱っているような場合や、プラグインを利用している場合などに発生しがちな不具合を取り上げて、移行の方法をXcode上で具体的に示している。デベロッパーにとっては参考になるはずだ。
ユーザーに気づかれない移行を目指すRosetta 2
Rosetta 2についても、最初に紹介されたのはキーノートでだった。そこでは大きな特徴として、高性能かつ互換性が高いこと、アプリのコードはインストール時に変換されること、プラグインなどは実行直前にダイナミックに変換することも可能であること、ユーザーにとっては意識せずに動作することなどが挙げられた。
また「Platforms State of the Union」でもRosetta 2は取り上げられた。Metalでも有効で高性能を発揮することが付け加えらたほか、いくつか新しいデモが示されたが、技術的な内容としてはキーノートと大差がなかったと言える。
一方「Explore the new system architecture of Apple Silicon Macs」のセッションでは、比較的詳しい技術的内容も明らかにされた。まず示されたのは、Rosetta 2で動作可能なアプリの種類だ。一般的なmacOSのアプリはもちろん、Mac Catalystを利用して作られたアプリ、ゲーム、JavaScript用のJITコンパイラーなどを含むウェブブラウザーなどが挙げられた。Metalを利用したアプリでも、Rosetta 2によって適切なApple Silicon上のGPUコマンドが生成されるという。さらに、機械学習を扱うCoreMLフレームワークを利用したアプリでも、Apple Siliconに内蔵されるニューラルエンジンを利用して動作するようになる。
次に、Rosetta 2によって実際のコードの変換が発生するタイミングについても説明された。それによると、1つは、App Storeからインストールするタイミング。もう1つは、どこからかダウンロードしたインストーラーのパッケージからインストールするタイミングだ。そして、こうしたアップル製の標準的なインストーラーを使わないアプリでも、初めて起動するタイミングで自動的に変換が実行される。その場合でも、最初だけDockの中でアプリのアイコンがバウンスする回数が多くなる程度だという。
またRosetta 2によるコードの変換は、セキュリティ的にも配慮されたものとなっている。コードは署名され、安全に保存される。また変換を実行したマシンでしか動作しない。こうしたセキュリティ設定は、OSをアップデートする際に更新されるので、変換済のコードはそのまま利用できるはずだ。
変換済のアプリを起動すると、当然ながら変換後のコードが動作する。ただし、プラグインのように、インストール時に変換されなかったコードについては、実行時に自動的に変換されるようになっている。
それでも、インテルCPUとApple Siliconには、細かな点でいろいろと違いがあるため、Rosetta 2で吸収しきれずにうまく動作しないアプリがあることも考えられる。たとえばRosetta 2は、インテルのAVX(Advanced Vector eXtension)と呼ばれるベクトル演算の拡張命令をサポートしていない。行儀のいいアプリであれば、事前にCPUがAVXをサポートしているかどうかを確認してから使うように作られている可能性もある。そうしたアプリでは問題ないかもしれないが、最初からAVXの存在を仮定して、いきなりそうした命令を使うようなアプリは、Apple Silicon上では動作しないだろう。
Rosetta 2は、多くの場合デベロッパーがアップデートをやめてしまったり、Apple Siliconへの移行をあきらめたような過去のアプリを動作させるためのものと考えられる。そのようなアプリにRosetta 2が対応できない部分が出てきてしまった場合、対処方法はほぼない。実際にはApple Silicon搭載Macが登場してみないと何とも言えないが、そのようなアプリがそれほど多くないことを願いたい。
画像クレジット:Apple