1 ポイント 投稿者 GN⁺ 2025-05-11 | 1件のコメント | WhatsAppで共有
  • 最新のSep 0.10.0は、AMD 9950X21 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件のコメント

 
GN⁺ 2025-05-11
Hacker Newsのコメント
  • Intelがコンシューマ向け製品でAVX-512対応のためにチップ面積まで何年も投資してきたにもかかわらず、ようやくライブラリがこれを使い始めた今になって、逆にAVX-512をコンシューマSKUから外してしまったのは本当にあきれる。AMDのAVX-512対応が特別優れているわけではなく、単にIntelが自分で投資したものを捨てた結果、AMDのコンシューマCPUにAVX-512が入る流れになったという皮肉な状況だ
    • Intelはいつも技術市場を作っては(Optane)、突然撤退して(Depth Cameras)消費者を混乱させるパターンを繰り返している。新技術に一気に突っ込み、普及しなければすぐやめる。Optane対応がLinuxカーネルでようやく成熟し始めた頃に打ち切り、奇妙なコスト削減戦略もある。歴史をさかのぼればIntel iAPX 432の頃から同じ失敗を繰り返している
    • 今回の記事ではAMD CPUでオリジナル: 18GB/s、AVX2: 20GB/s、AVX512: 21GB/sという速度が確認されている。AVX-512の利点はAVX2比でほとんどない。IntelのコンシューマCPUはEコアでもAVX2をサポートしており、ベンチマークはシングルスレッドだ。Intelはより多くのコアを載せるためにチップからAVX-512を外し、その結果最上位は24コア、AMDは16コアになっている。AVX2→AVX512の差がわずかなので、マルチスレッドではコア数の多い側が勝つかもしれない。実際のワークロードの大半ではAVX-512よりコア数増加の利点のほうが大きく、一部の非常に特殊な作業を除けばIntelの判断は合理的だったと思う
    • まもなくAVX-10が登場する予定で、AVX-512とほぼ同じ機能を持つ見込みだ(何が違うのかは私も分からない)
    • 今回の記事で最も興味深かったのは、AMD 9950XでAVX2パーサーがAVX-512ベースのパーサーより約10%速かった点だ(20GB/s対21GB/s)。結局のところ、AVX-512は実際のコンシューマには大して役立たないように見える。CSVパースが20GB/sも出れば文句はない。対応の有無を気にするのはアセンブリ愛好家くらいだ
    • Intelがこんなに間抜けなことをしているのは本当に信じがたい
    • 慰めになるとすれば、Sepは可能なときは追加設定なしでもAVX-512を使う。JITランタイム上でうまく動くので、意図せず最低性能基準をターゲットにしていても損をすることはない
    • Intelはソフトウェア対応もいまひとつだ。私のノートPCのiGPUもかなり良いのに、PyTorchなどでちゃんとサポートされておらず残念だ。llama.cppとVulkan推論はうまく動くので、ほかのソフトウェアもこういう形で対応してほしい
  • 各文字ごとに4回の比較(\n\r;)をしてから3回のor演算をする代わりに、よくあるトリックでシャッフル1回、比較1回、or演算0回にできる。このトリックをブログで紹介したので参考までに。とはいえこの記事でもvpternlogdvpor演算でor演算を減らしている
  • IntelがコンシューマCPUに遅いコアを入れなければならないとか、「マルチポンピング」の検討もなくAVX-512を全部外してしまう判断は見苦しい
    • この選択の主因は10nmプロセスの問題だ。不良率が高くコストも高すぎたので、できるだけチップを切り分けてAtom系コア/低消費電力マーケティングで利益を出そうとした。高価格帯製品はサイズを大きくしてマージンを削り、サーバー/クラウド市場を守ろうとした。結局は収益性も落ち、市場シェアも失ったが、とにかくやってみようとはしていた
  • Sepのリリース(2023年6月)から2年で約3倍の高速化を達成したという主張は、ハードウェアの飛躍も考えると議論の余地がある
    • 同一ハードウェア上でのソフトウェア(0.9.0と0.10.0)の向上幅は17%で、0.9.0の13088に17%足すと15375。0.1.0の7335と比べれば約2.1倍の向上だ
    • 同一ハードウェア上でsepの以前のバージョン比3GB/s向上と主張しており、実際の速度とハードウェア情報も透明に記載されている
    • 今はムーアの法則のような時代でもないので、ハードウェアだけで3倍の高速化を期待するのは難しい。この程度でも現代では十分印象的な成果だと思う
    • ハードウェアの飛躍を考慮せず3倍向上と主張するのは確かに論争の余地があるが、それでも年ごとのソフトウェアの実効性能を見る一つの観点としては興味深い
    • ベンチマークのグラフがCPU世代を4つも飛ばしていて、急に「大幅性能向上」に見えるので信頼しにくい
  • Arthur Whitneyがこの結果に刺激されて1行コードでこれを上回るか、shaktiエンジンの更新とともに1行で記録を破るか、あるいはニュース更新が来ることを期待したい。今後の進展に期待
  • 誰が1000万行のCSVをこの速度で処理しなければならないのかと考えるだけでぞっとする
    • 私にもそういう経験がある。最初は小さなデータ量に合わせてCSVを選ぶ。非開発者、特にExcelに強い人たちが読みやすいので、ログやプロセスもCSVでうまく扱える。だがデータが10倍、100倍に膨れ上がると、数十億行規模のCSVを最適化して高速にingestすることが現実的な必要になる。こうした最適化は、内部プロセスを徐々により適したフォーマットへ移行する時間を稼ぐ手段でもある
    • CSVは内部でも思ったより一般的なフォーマットで、圧縮(deflate)しやすい利点もある。以前、CSVがNICカード速度でNetflowデータを吐き出すコードを扱ったことがある。個人的には、そこまで複雑な処理をするならいっそProtocol Buffersを使えばよいと思う。protobufはそれほど難しいフォーマットでもないのに、なかなか導入されない
    • 21GB/s級のCSVを処理した結果を保存するという意味のほうがもっと恐ろしく感じる。どれだけ有用な集計でも、その速度なら結局どこかに蓄積されるはずで、どうするのか気になる
    • 多くの欠点があるにもかかわらず、今でもCSVが最も一般的なデータ交換フォーマットだと思う
    • 金融業界ではCSVなら誰でも共有でき、テキストベースなのでどこにでも放り込んで処理できる
    • 経理部門が年末に送ってくるcartesian productファイルを例にできる
    • 実際にこういう旧式のCSVを扱わなければならず苦労している立場だ
    • ほぼすべての場合でHDF5はCSVより優れている。それでも使われ続けるのは、無知、怠惰、あるいは「動いているから」という理由以外では説明しにくい
  • アセンブリコードを期待して開いたのにC#で驚いたし、印象的だった。素晴らしい結果だ
    • 最新の.NETは、SIMDとベクターintrinsicsを最も深く統合した「高級言語」だ。MicrosoftのTanner Goodingが多くの進展を牽引しており、関連するブログ記事も素晴らしい
  • 本文で21GB/sのコードが正確に何をしているのか明確に定義されていない点が気になる。たとえば、パース対象のフォーマットが具体的に何なのか(CSVでのクオート処理など)、パース後に結果をどう使うのか(データ構造に入れるのかなど)が不明だ
    • 記事内で計算されたns/rowは約27ns/row(毎秒37,000行程度)だが、もし21GB/sなら1行あたり570KB程度になるので、かなり不自然なベンチマークに見える
  • 私の経験では、カスタムSIMDコードで現代のコンパイラの自動ベクトル化に対して大きな利益を得るのは難しかった(特にベクトル化しやすいコードでは)。ただしJSONパースのような特殊なケースは少し違う
  • 最近300GBのCSV抽出データを扱ったが、操作や整合性検証にあまりに時間がかかり、こういう高速CSVパーサーが切実に必要だ
    • なぜ浮動小数点データ保存に特化したフォーマットを使わないのか理解できない。HDF5のほうがはるかに良い代替だ