Haskell beats C
で、この拡張の結果、合成性のある(非ボックス化)vector の抽象度の高いコードで、SSE を使った手書きの C コードに勝つ性能を発揮できるようになったそうです。
2013-02-05 15:39:30Dot Product の処理性能では、普通の手書きの C コードには勝てるけれど、流石に GotoBLAS を使っての処理には負けるみたいですね。Gaussian RBF の処理性能なら、GotoBLAS にも勝てるようです。
2013-02-05 15:40:59ただ、Gaussian RBF の処理性能に関しては、配列の要素数が多くなってくると、SSE を使わないバージョンの vector でも(メモリトラフィックを削減できる)ことにより Goto BLAS に勝てるそうですが。
2013-02-05 15:41:11Dot ProductでHaskellの方が速くなる理由としては、「VectorからMultiStream(ベクトル演算を使った処理のストリーム)に変換を行う時に、これから行われるメモリアクセスのパターンが分かっているのでプリフェッチ命令を適切な形で挿入できる」ことを挙げてますね
2013-02-05 15:45:25(言及してませんでしたが、GHC HEAD にプリフェッチ命令を使うための primitive が入ってます。 https://t.co/tFW43gGx )
2013-02-05 15:45:45(で、この primitive を使ったコードが、primitive パッケージの simd branch と vector パッケージの simd branch に入ってます https://t.co/Bh2f3loe https://t.co/AbgN41aU )
2013-02-05 15:47:01あと、vector ではベクトル演算を利用するために mfold や mzipWIth などの特別な関数を使いますが、DPH は元々ベクトル化のための仕組みを持っているので、DPH では特別な関数を用意しなくても実装の内部でベクトル演算を利用するようにできるそうです。
2013-02-05 15:47:15実際、前に公開された DPH の SIMD 対応の記事では、利用するモジュール名が違うだけで後はいつものままのコードでしたね。 http://t.co/QrHfRS9Y
2013-02-05 15:47:29.。oO(モジュール名を変えているのは、今のところ GHC HEAD のベクトル演算用の primitive が LLVM バックエンドにしか対応していない(そして Windows 環境では利用できない……[https://t.co/5DU7XvuW ] )からだと思います。)
2013-02-05 15:48:22現在の DPH の実装は SIMD 命令用に特化したものではないので性能に揺らぎがありますが、SIMD 命令を使ってそこそこ高速に処理できる上に、CPU 数の増加に応じてスケールしていくみたいで素晴らしいですね。
2013-02-05 15:49:36あっ、さっき言ったのは、現在の DPH ライブラリではなく simd branch 版 vector を使った simd branch 版 DPH [https://t.co/fgu0h8cx ] の話ね。念のため。
2013-02-05 16:00:48ICFP に再投稿された新しいバージョンで追加された内容
あっ、"Haskell beats C" が ICFP 2013 に再投稿されてますね。 http://t.co/eGn05XgFy0
2013-03-30 03:26:50"Haskell beats C" の新しいバージョンですが、ページ数が増えたからか、対象読者が異なるからか、実装の説明が詳しくなっていますね。
2013-03-31 23:11:38ただし、説明用に本来のコードにはない型を加えているので、実際の vector のコードを見る時は MultisC = MultiStream である点や MultisP は存在してない点に注意してください。
2013-03-31 23:11:51"5.1 Prefetching and loop unrolling" では、ただ単に説明を詳しくしているだけでなく、新しく入れた変更 [ https://t.co/xavB3tBLjf ] に基づいた説明をしてますね。
2013-03-31 23:12:18"5. Evaluation" の性能比較ですが、つっこみがあったのか、比較対象がかなり広がっていますね。
2013-03-31 23:14:23Cとの比較では、普通のCコード(を普通にコンパイルしたもの)と、SSE を使って手書きで最適化したCコードを使っていましたが、このうち普通のCコードを GCC の自動ベクトル化機能を使って最適化するようにしてますね。
2013-03-31 23:15:00(正確には -O3 -msse4.2 -ffast-math -ftree-vectorize -funroll-loops で最適化したコードを使うようにしたそうです。)
2013-03-31 23:15:27で、自動ベクトル化機能を使って最適化した普通のCコードと、SSE を使って手書きで最適化したCコードの両方に勝てることを確認しています。
2013-03-31 23:15:42もちろん、手でプリフェッチ命令を適切なところに入れていけば C でも同様の性能を出せるでしょうけれど、コードの抽象性を失わせずに適切なところにプリフェッチ命令を入れるようコンパイルできるのがこの手法の利点という話です。
2013-03-31 23:16:34また、従来の vector と SIMD 命令を利用できるようにした vector との間での、Haskell 同士の性能比較を行う節が増えてます。
2013-03-31 23:17:07Gaussian RBF に関しては、融合変換が大きく効いてくることから、融合変換のできないCとの比較は藁人形相手に戦っているようなものということで、新しく式テンプレートによって融合変換できるC++との比較を行う節が追加されています。
2013-03-31 23:18:50残念ながら、現時点では SIMD を使えるようにした改良版の vector よりも C++ のライブラリの方がより高い性能を発揮できるようです。(Eigen をきちんと使った場合、L3 キャッシュから漏れるぐらいのメモリを利用した場合の Boost.uBLAS など)
2013-03-31 23:20:33負けてしまった原因についてもきちんと分析されているので、将来的にこれらC++のライブラリにも勝てるようになると良いですね。
2013-03-31 23:21:08