- 最新のSep 0.10.0は、AMD 9950Xで21 GB/sという驚異的なCSVパース速度を達成
- AVX-512対応とマスクレジスタ問題の克服により、性能が大幅に向上
- 新しいAVX-512-to-256パーサーは、AVX2や従来のAVX-512パーサーを上回る結果を示した
- マルチスレッド環境では100万行を72msで処理し、8 GB/sの帯域幅を記録
- 継続的なソフトウェアおよびハードウェア最適化により、2年で約3倍の性能向上を実現
Sep 0.10.0リリースと性能向上の概要
- Sepは最近の0.10.0リリースで、AVX-512対応CPU(例: AMD 9950X, Zen 5)向けの最適化を行い、ベンチマーク結果も更新した
- 最新版では、低レベルのCSVパースで21 GB/sという非常に優れた成果を記録
- 以前のバージョンの18 GB/sと比べても、大きな性能向上となっている
- 改善内容はSepのGitHubリリースとREADMEで詳しく確認できる
- 本文では、.NET 9.0のAVX-512マシンコードの非効率性を克服したSIMDベースのC#コードと、x64 SIMDアセンブリによる性能向上の過程を説明している
Sepの性能向上の歩み
- Sepの初期0.1.0から0.10.0、.NET 7.0から9.0、AMD 5950X(Zen 3) から 9950X(Zen 5) への進化が視覚的に示されている
- ベンチマークは単一スレッド基準で、各リリースごとに多少の変動があり得る
- 核心となるメッセージは、大規模なリファクタリング(0.2.0の内部構造の書き直し)や小さな変更を積み重ねた最適化が、継続的な性能改善につながったことだ
- ハードウェアとソフトウェアの相乗的な進化により、平均して2年で約3倍向上した21 GB/sのパース速度を達成
- ハードウェア世代間(5950X→9950X、4.9→5.7GHz)の変化だけでも、1.2倍超の向上を裏付けている
AVX-512コード生成とマスクレジスタの問題
- Sepは0.2.3からAVX-512をサポートしていたが、AVX-512のマスクレジスタ(k1-k8) 活用には限界があった
- .NET 8ではマスクレジスタへの直接サポートがなく、通常レジスタ間での繰り返しコピーや変換が性能低下の要因になっていた
- 専用のAVX-512対応CPUがなかった初期には、Xeon Silver 4316で限定的にテストし、最速であることを確認していた
9950XへのアップグレードとAVX-512 vs AVX2の比較
- 最近、CPUをZen 3(5950X)からZen 5(9950X) にアップグレードし、Sepのベンチマークを実行した結果、18 GB/sに到達した
- AVX-512とAVX2パーサーを直接比較したところ、やや意外なことにAVX2が約20 GB/sで、AVX-512より約10%高速だった
- これは、.NET JITにおけるマスクレジスタ処理の非効率が依然として問題であることを示唆している
パーサーコード、アセンブリ解析、新しいAVX-512-to-256パーサー
- Sepのすべてのパーサーは16K単位のchar spanを処理し、SIMDレジスタ(Vector256など)ベースの比較演算を利用する
- SIMDで特殊文字(改行、引用符、区切り文字など)を高速に判定し、ビットマスクに変換して集合演算の最適化を実現している
- AVX-512ベースのパーサーは、マスクレジスタ(k1など)と通常レジスタ(zmmなど)の間を繰り返し移動するため、余分な演算が多かった
- 0.10.0ではMoveMask呼び出しを前倒しし、不要なマスク変換を最小化することで、アセンブリ命令数を削減した
- AVX2パーサーはマスクレジスタがないため構造がはるかに単純で、AVX-512より実質的に高速だった
- 新しいAVX-512-to-256パーサーは、AVX-512でデータを読み込み、256ビット変換命令でマスク処理問題そのものを回避することで、実装を簡潔にしつつ21 GB/s超の性能を実現した
各種パーサーのベンチマークまとめ
- 環境変数で全パーサー種別のベンチマークを比較した結果、AVX-512-to-256パーサーが21.5 GB/sで最速だった
- AVX2ベース、Vector256ベースのパーサーも、わずか5%差以内に収まる近い性能を示した
- Vector128、Vector512ベースのパーサーはAVX2比で5〜10%遅く、特にVector512パーサーはVector128よりも遅かった
- IndexOfAnyパーサーは他のSIMDパーサーに比べて大幅に遅く、Vector64は9950Xで高速化されないため性能が非常に低かった
- AVX-512およびAVX2ベースのSIMDパーサーが、同種のCSVパーサーと比べて圧倒的な性能を示した
上位ベンチマーク: 5950Xと9950Xの比較
- 100万件のパッケージ資産行を基準に、Sep_MTは9950Xで72ms(8GB/s)、5950Xで119ms(4.9GB/s)を記録
- 実負荷データ(floatなど)でも、9950Xでマルチスレッド時に約8GB/sの帯域幅を達成
- 世代の変化(5950X→9950X)により、実アプリケーションのパースでも約1.5〜1.6倍の改善効果が見られた
- 競合CSVライブラリ(Sylvan、ReadLine、CsvHelperなど)と比べても、圧倒的なスループットと最小限のリソース割り当てを実証した
結論と要約
- Sep 0.10.0は、ソフトウェア最適化と**最新ハードウェア機能(AVX-512、高クロック)**の組み合わせにより、CSVパース性能の限界を押し広げた
- 最新のSIMDアルゴリズム設計、.NET JITコードおよびアセンブリ構造の改善が革新の核心となっている
- 短期間での累積的な性能改善とアーキテクチャ世代交代の効果は印象的だ
- SepはCSVパース分野で、実質的に業界最高水準の高性能、マルチプラットフォーム、拡張性を提示している
1件のコメント
Hacker Newsのコメント
\n、\r、;、“)をしてから3回のor演算をする代わりに、よくあるトリックでシャッフル1回、比較1回、or演算0回にできる。このトリックをブログで紹介したので参考までに。とはいえこの記事でもvpternlogdとvpor演算でor演算を減らしている