2021/10/05 22:40 検証方法に間違いがあったため(VS for Mac がデバッグありの実行になっていました)、再度検証し直し記事も訂正しております。ご指摘ありがとうございました。
はじめに
.NET 6 では FileStream がほぼ完全に書き直されており、速度と信頼性のが高まりました。また、複数のバッファーに対応した(Scatter / Gather IO)新しい API が導入されています。Scatter / Gather IO を使用すると、単一の sys-call で複数のバッファーを渡すことにより、高コストの sys-call の数を減らすことができます。
devblogs.microsoft.com
Visual Studio for Mac 2022 Preview 1 on M1 Mac で試したら...
Windows と Linux でのベンチマーク結果は公式ブログにデータがありましたので、Mac ではどのような結果になるか試してみました。
公式ブログの記事内のコードから、サンプルプロジェクトを作成しました。
github.com
ベンチマークのライブラリは、BenchmarkDotNet を利用しているようなので、同じように構成しました。
github.com
Visual Studio for Mac 2022 Preview 1 で実行した結果ですが...
// * Summary * BenchmarkDotNet=v0.13.1, OS=macOS Big Sur 11.6 (20G165) [Darwin 20.6.0] Apple M1 2.40GHz, 1 CPU, 8 logical and 8 physical cores .NET SDK=6.0.100-rc.1.21463.6 [Host] : .NET 6.0.0 (6.0.21.45113), X64 RyuJIT DefaultJob : .NET 6.0.0 (6.0.21.45113), X64 RyuJIT | Method | Mean | Error | StdDev | |------------ |----------|----------|----------| | Write | 47.92 ms | 1.109 ms | 3.271 ms | | WriteGather | 48.51 ms | 1.567 ms | 4.621 ms |
なんと上記の通り、WriteGather()
の方が遅いという結果となりました...
ベクトル化 IO がうまく機能していない
詳細を解析していないのでなんとも言えないですが、公式ブログでは、Linux ではベクトル化 IO が機能しているとのことでしたが、Mac ではなんらかの理由でうまくベクトル化 IO が機能していない感じです。
一応、.NET 6 と Darwin のソースを調べてみましたが、pwritev() はサポートしているようですが、ベクトル化 IO がうまく機能していない詳細な原因まではわかりませんでした。
...と、いったんは思ったのですが、よく見ると、ベンチマーク結果が、X64 となっているので、Rosetta 2 による変換が入っているのが気になります。
ちなみに、意識せず x64 版がインストールされていたのは、dotnet-maui-check でインストールしたからでした。
Arm64 版 SDK をインストールして再度チャレンジ
というわけで、.NET 6 RC1 SDK をいったん全て削除して、再度 Arm64 版 SDK をインストールして Visual Studio for Mac 2022 Preview 1 で再度試したところ、今度は、無事成功しました。しかも、WriteGather()
の方が速く、ベクトル化 IO も効果を発揮しています。
// * Summary * BenchmarkDotNet=v0.13.1, OS=macOS Big Sur 11.6 (20G165) [Darwin 20.6.0] Apple M1, 1 CPU, 8 logical and 8 physical cores .NET SDK=6.0.100-rc.1.21463.6 [Host] : .NET 6.0.0 (6.0.21.45113), Arm64 RyuJIT DefaultJob : .NET 6.0.0 (6.0.21.45113), Arm64 RyuJIT | Method | Mean | Error | StdDev | |------------ |----------|----------|----------| | Write | 45.11 ms | 0.950 ms | 2.772 ms | | WriteGather | 40.23 ms | 1.304 ms | 3.844 ms |
今回得た知見
今回の検証で以下のような知見を得ました。
- M1 Mac で .NET 6 の、Scatter/Gather IO は Arm64 版 でしか有効にならない。x64 版では効果がない。
- M1 Mac で .NET 6 SDK の、x64, Arm64 を両方インストールした場合、同じ場所に配置され、後にインストールした方が有効となる。side by side にはならない。
- M1 Mac で .NET 6 SDK の、x64, Arm64 を切り替えたい場合、念のため SDK をいったん削除してから再インストールした方が無難そう。
- M1 Mac で Visual Studio for Mac 2022 Preview 1 では Arm64 版 SDK でのデバッグ実行がまだ正常動作しない。x64 版 SDK/Rosetta 2 ならデバッグ実行できる。
というわけで、Visual Studio for Mac 2022 の今後のリリースに期待します。
.NET 6 の更新情報は以下をご覧ください。
hiro128.hatenablog.jp