2024年06月27日
MSYS2のQEMUを使用する場合はUCRT64版を推奨
MSYS2 を使用する場合、MinGW64 環境と UCRT64 環境の 2 つがあります。
MinGW64 は馴染み深い Microsoft Visual C++ の msvcrt を C RunTime(CRT)ライブラリに使用します。一方 UCRT64 は Windows 10 から使用可能な Universal CRT を使用します。(UCRT64 は 2020 年ごろから開発が始まった比較的新しい環境です。)
今まではどちらも同じようなものだと思っていたので惰性で MinGW64 を使い続けてきましたが、同じバージョンの QEMU が UCRT 版(mingw-w64-ucrt-x86_64-qemu)は期待通り動くのに、MinGW64 版(mingw-w64-x86_64-qemu)は動かないケースがありました。今後は特別な理由が無い限り UCRT64 環境を使おうと思います。
詳細は以下になります。
MinGW64 は馴染み深い Microsoft Visual C++ の msvcrt を C RunTime(CRT)ライブラリに使用します。一方 UCRT64 は Windows 10 から使用可能な Universal CRT を使用します。(UCRT64 は 2020 年ごろから開発が始まった比較的新しい環境です。)
今まではどちらも同じようなものだと思っていたので惰性で MinGW64 を使い続けてきましたが、同じバージョンの QEMU が UCRT 版(mingw-w64-ucrt-x86_64-qemu)は期待通り動くのに、MinGW64 版(mingw-w64-x86_64-qemu)は動かないケースがありました。今後は特別な理由が無い限り UCRT64 環境を使おうと思います。
詳細は以下になります。
事の発端は、業務で RISC-V の RVV 命令を使用したベクトル版数学ライブラリを試作していた時のことです。
当初はプロプライエタリの riscvOVPsimPlus シミュレータで開発を行っていたのですが、Imperas 社が Synopsys 社に買収された影響でサイトの統合や切り替えが発生し、シミュレータが一時的にダウンロードできない状況が発生しました。弊社は商用版ライセンスを持っているので専用サイトからダウンロードは可能でしたが、今後のことを考えるとオープンソースのシミュレータにも対応した方が良いと判断し、QEMU 対応を行いました。
今思うと不思議ですが、この時なぜか QEMU は UCRT 版を使用していたので、riscvOVPsimPlus と全く同じ結果が得られ、特に問題なく開発は完了しました。
その後しばらくしてから、今度は弊社の PARTNER デバッガを QEMU RISC-V に対応させる必要が出てきたため作業を行いました。QEMU のビルドは長年 MinGW64 環境で行ってきたので、この時も MinGW64 でビルドしました。
すると、非常に微妙な誤差で数学ライブラリのテストが fail しました。浮動小数点数なのでシミュレータの実装に依存する可能性もあるかもしれないと思い、MSYS2 の QEMU で実行した所、特に問題ありませんでした。MSYS2 の方がバージョンが新しいので、何らかのバグが修正されたのか、シミュレーションがより正確になったのか、など色々な要因が考えられたので一つ一つ潰していった結果、最終的には、なんと全く同じバージョンの QEMU で、おそらく全く同じコンフィギュレーションでビルドされているはずの MSYS2 のツール同士でも誤差が発生することが判明しました。
最終的に QEMU を UCRT 環境でビルドすることで期待通りの結果が得られました。
当初はプロプライエタリの riscvOVPsimPlus シミュレータで開発を行っていたのですが、Imperas 社が Synopsys 社に買収された影響でサイトの統合や切り替えが発生し、シミュレータが一時的にダウンロードできない状況が発生しました。弊社は商用版ライセンスを持っているので専用サイトからダウンロードは可能でしたが、今後のことを考えるとオープンソースのシミュレータにも対応した方が良いと判断し、QEMU 対応を行いました。
今思うと不思議ですが、この時なぜか QEMU は UCRT 版を使用していたので、riscvOVPsimPlus と全く同じ結果が得られ、特に問題なく開発は完了しました。
その後しばらくしてから、今度は弊社の PARTNER デバッガを QEMU RISC-V に対応させる必要が出てきたため作業を行いました。QEMU のビルドは長年 MinGW64 環境で行ってきたので、この時も MinGW64 でビルドしました。
すると、非常に微妙な誤差で数学ライブラリのテストが fail しました。浮動小数点数なのでシミュレータの実装に依存する可能性もあるかもしれないと思い、MSYS2 の QEMU で実行した所、特に問題ありませんでした。MSYS2 の方がバージョンが新しいので、何らかのバグが修正されたのか、シミュレーションがより正確になったのか、など色々な要因が考えられたので一つ一つ潰していった結果、最終的には、なんと全く同じバージョンの QEMU で、おそらく全く同じコンフィギュレーションでビルドされているはずの MSYS2 のツール同士でも誤差が発生することが判明しました。
$ /ucrt64/bin/qemu-system-riscv64.exe -M virt -cpu rv64,v=true,vlen=256,elen=64,vext_spec=v1.0 -m 2G -nographic -semihosting -bios basic_test.out $ echo $? 0 $ /mingw64/bin/qemu-system-riscv64.exe -M virt -cpu rv64,v=true,vlen=256,elen=64,vext_spec=v1.0 -m 2G -nographic -semihosting -bios basic_test.out rvv_log( 0.0000484967262970 = 0x3f096d1ed3c80000 ) is difference. -9.9340142613292777 -9.9340142613292759MinGW64 と UCRT64 で動作に差があるとはこの時は夢にも思っていなかったので、もし最初に UCRT 版 QEMU で開発を進めていなければ、やっぱり商用のシミュレータの方が正確なんだなあ、などと勘違いしたままうやむやで終わっていたかもしれません。幸運でした。
最終的に QEMU を UCRT 環境でビルドすることで期待通りの結果が得られました。