Red Hat で Solution Architect として OpenJDK を担当している伊藤ちひろ(@chiroito)です。
この記事は、Red Hat Developerのブログ記事、How Red Hat ported OpenJDK to 64-bit Arm: A community history | Red Hat Developer の翻訳記事です。
今年はArm社にとって大変な1年でした。Arm社はコンピュータ・プロセッサのRISC(Reduced Instruction Set Computing)アーキテクチャを設計している会社です。Armベースのコンピュータが当分の間重要になるというニュースは、主流メディアにまで届きました。2019年末には、Amazon Web ServicesがArmベースのGraviton2サーバーを発表しました。2020年6月には、AppleがMacintoshコンピュータをApple siliconに移行させる計画を発表しました。これはつまりArmです。
長年、Armサーバに携わってきた者にとって、この変化は長い間待ち望んでいたものです。
はじめに
2011年のある日のことです。私は、Red HatのリードArmアーキテクトであるJon Masters氏と共にThe Wrestlers(英国ケンブリッジの技術者コミュニティのお気に入りのタイ料理店)で昼食をとっていました。彼はエキサイティングなニュースを話していました。Armが64ビットアーキテクチャを開発し、Red HatがRed Hat Enterprise Linux(RHEL)をそれに移植するというのです。これを実現するためには、いくつかの問題を解決する必要がありますが、その中でも特に難しい問題がありました。新しい64ビットアーキテクチャ用のソフトウェアには、Javaが含まれていませんでした。Javaは多くの企業向けソフトウェアの重要なコンポーネントですから、このニュースはかなり大きなものでした。
誰かが移植版を書かなければならなりません。2人の専門家が約1年でOpenJDKの素朴な移植版を書けると聞いていましたが、私はそれしか知りませんでした。私のチームがやろうとすると、現場で学ばなければなりません。
私は、このような大きな仕事に携われることに興奮していました。しかし、成功の保証もないのに、このような大きなプロジェクトを始めることをRed Hatはどうやって正当化するのでしょうか?私は、自分たちがやらなければ、誰かにお金を払わなければならないと主張しました。それには莫大な費用がかかる。ならば、自分たちでやったほうがお金の節約になるのではないか。宣伝にもなるし、仲間もつくれる。しかし、社内でやることには、もうひとつ深い理由がありました。私たちは、OpenJDKのサポートチームを立ち上げていました。移植版をすべて作成することで、他では得られない経験を積むことができます。Red Hatの経営陣も同意してくれたので(それ以来、一貫してプロジェクトをサポートしてくれています)、私たちは実行に移すことができました。
私はこのプロジェクトのエンジニアの一人になることを決意しましたが、一人ではできませんでした。幸いなことに、Andrew DinnがJavaチームに加わることになりました。彼は長い間Javaに携わってきており、Lispマシンや論理言語のコンパイラを書いた経験もある。彼とならうまくやっていけるでしょう。
ただ、ひとつ心配なことがありました。他の人が先に移植してしまったらどうしよう。もし、他の人が先に移植してしまったら、せっかくの努力が無駄になってしまうかもしれません。そんなことにならないためには、先手必勝で人前で仕事をするしかありません。早くやって、うまくやって、無料にする。そうすれば、みんなが来てくれます。
プロジェクトを開始
ただ、問題が1つ、いや2つありました。まず、AArch64プロセッサが存在しなかったこと。また、Arm社を説得して、必要な情報を詳細に提供してもらうことも容易ではありませんでした。ドキュメントの問題は、Arm社のPhilippe Robin氏の協力と粘り強さで解決しましたが、ハードウェアの不足の方が問題でした。OpenJDKのすべてをシミュレーションで動かすことは可能ですが、当時のシミュレータは非常に遅かったのです。さらに悪いことに、OpenJDKはOSを呼び出さなければなりません。Javaを起動する前に、シミュレータ上ですべてのLinuxをブートストラップさせる必要があります。
Andrew Dinnは、あるカンファレンスの朝食時に、私がシャワーを浴びている間に何をすべきかを見つけたと興奮気味に話したことを覚えています。シンプルで機能的な命令セット・シミュレータを使用しますが、それは自分たちで生成したAArch64コードのためだけです。OpenJDKのJVMの残りの部分はC++です。C++はIntel x86ベースのPCでネイティブにフルスピードで実行できます。C++ から Java への呼び出しはすべてシミュレータに入り、Java から C++ への呼び出しはすべてシミュレータを出て x86 コードに戻ります。でも、AArch64のシミュレータ・ライブラリはどこで手に入るのでしょう?私は「書きましょう」と言った。「RISCなんだから。難しいことはないだろう」。
スタートしたのは2012年の6月。Andrew Dinnがシミュレータを書くのに少し時間がかかり、私はアセンブラと初期起動コードの作成に取り掛かりました。数ヵ月後には、Javaのバイトコードを実行できるようになりました。自分たちでシミュレータを書いてみようと思い立ったのです。複雑なブレークポイント条件を設定したり、命令のトレースを記録して、JVMがクラッシュしたときの命令の履歴を確認できました。その結果、最初の移植作業はすぐに終わりました。ログを見返してみると、2012年10月4日に「Enough for Hello, World! 」のエントリが見えます。この日は大事な日でした。コンソールに "Hello, World!"と出力するまでに、Javaは約25万バイトコードをクラッシュせずに実行し、仮想マシンの多くを動かさなければなりません。
そして3人になった
2013年の夏には、3人でプロジェクトを進めていました。Linaro社からは、元Arm社のJavaエキスパートであるEdward Nevillがプロジェクトに参加しました。彼は実際のハードウェアを手に入れた最初の人物です。私は、自分たちが作った小さなAArch64シミュレータにとても満足していたので、誰かが実機でデバッグしてくれるのはとても嬉しかったですね。苦労するだろうと思っていました。しかし、命令キャッシュのフラッシュに関する小さな問題と、浮動小数点フラグの問題を除けば、すべてうまくいったのです。これには驚きました。私たちは、Arm社のドキュメントをもとに、自分たちでシミュレータ、コンパイラ、アセンブラを書いたのです。独立した検証を受けたわけではありませんが、私たちはそれを正しく理解していました。
Edward は非常に大きな助けとなり、2014年の初めには動作する移植版が完成しました。 Red Hatはパートナー企業への早期リリースの出荷を開始し、私たちや他の企業はバグの修正やパフォーマンスの向上を続け、2015年3月2日にAArch64ポートはOpenJDKプロジェクトのメインの一部となりました。Oracle は素晴らしく、厄介な統合プロセスを助け、励ましてくれました。
統合と(超)ロングテール
動くJVMと本当に優れたJVMの間にはかなりの違いがあります。Intel/x86のOpenJDKにどれだけの時間が費やされたのかはわかりませんが、エンジニアとしては何十年もかかっているはずです。AArch64の移植版を競争力のあるものにするのは本当に大変なことでしたが、私たちには助けがありました。AArch64のシリコンメーカーやその他の企業からも参加してもらい、今では世界中の人たちが移植に取り組んでいます。
これこそが、Red Hatのオープンで協力的なアプローチが真価を発揮するところです。他者とパートナーシップを結ぶことで、純粋な自社ソフトウェア開発に比べて大きな相乗効果を得られます。
しかし、それだけではありません。Oracle社が64ビットのArm上でJavaを動かしているという話を聞いていたので、それが我々のポートなのかと思っていました。しかし、その移植版は、Oracle社がすでに持っている(32ビット)Armの移植版をベースにした独自のものでした。 Javaの本家が我々よりもはるかに良い成果を得ているのではないかと心配になりました。最終的には、Oracle社の移植版を使ったことのある人が親切にも「心配することはない」と言ってくれました。しかし、Oracle社が自分で移植版を書いたのは不思議でした。Oracle社は、最初から我々のコードをすべて使用する許可を得ていたのです。それなのに、なぜまた書くのでしょうか?
最終的にOracle社は、Armの32ビットと64ビットの両方の移植版を解放しました。その結果、OpenJDKには2つのAArch64移植版が残ることになりました。そして2020年11月12日、Oracleは今後のリソースを64ビットのArm移植版の1つに集中させることを決定したと発表しました。それはRed Hatで始めたAArch64移植版です。OracleのメンテナンスリリースであるJDK 8の64ビットArmサポートも、私たちの移植版をベースにしています。
最近、Appleは大騒ぎしながら、AArch64を実装したApple M1チップを発表しました。OpenJDKはそのプロセッサに対応しており、5年前から対応していました。しかし、OpenJDKには、OSとCPUの組み合わせごとに固有のレイヤーがあります。誰かがその作業をしなければなりませんでしたが、すぐに2人のボランティアが現れました。Microsoft社とAzul社の2社が協力してくれました。Microsoft社は、OS-CPUのレイヤーをWindows/AArch64にも移植しました。
まとめ
では、なぜこのようなことが起こったのでしょうか?それは、OpenJDKの開発者コミュニティが決定したからです。それは、私たちの小さなチームが早期に実用的な移植版を提供し、それをOpenJDKのメインラインに導入し、参加したいと思うすべての人を歓迎したからだと思っています。可能な限り多くの議論をオープンにしました。人々はボランティアで参加し、私たちはコミュニティになりました。私たちは、このコミュニティとともに、自分たちだけでは考えられないほどの成果を上げることができました。しかし、2014年の初めに作業用の移植版をリリースしていなければ、これらのことは起こらなかったでしょう。