Ut Video Codec Suite 12.1.0 では AVX 命令を使って高速化しました。

さて、このコード、(狭い意味で) AVX になって追加された命令を使っているわけではなくて、レガシー SSE 命令の VEX プレフィックス版を使っているだけです。レジスタが足りないとかそういった問題も無いので、AVX 版をレガシー SSE 版に容易に書き変えることができ、しかも Sandy Bridge 上では実行速度は変わりません(計測誤差未満)。

レガシー SSE 版に書き換えたコードは SSSE3 の命令 (PSHUFB, PALIGNR) までを使っており、Conroe 以降で走らせることができます。このコードは Nehalem では Sandy Bridge と同程度の高速化が見込まれます。Penryn ではそれほどではないものの、C++ で書いた1バイトずつロードストアするコードと比べればちょっとは速くなります。しかし、Conroe ではシャッフル関係命令がかなり遅いせいで、劇的に遅くなります。そもそも、このコードは元々レガシー SSE で書いたもので、その当時は Q6600 (Conroe ベースの Core 2 Quad)で開発していたせいで劇的に遅くなったため、一度は捨てていたのです。ファイル消さなくてよかった。

今のルーチン選択方法ではサポートされる命令だけを基準にしているため、「他の SSSE3 をサポートする CPU では速くなるけど、SSSE3 をサポートする最低ラインである Conroe では劇的に遅くなる」というケースをうまく扱えません。SSE4.1 以上で実行できる扱いにするという方法だと一見問題が解決されますが、それは筋が悪いです。

じゃあマイクロアーキテクチャを基準にして選択するか、ということになりそうですが、これも話は単純ではありません。ローエンドブランドの CPU だと同じマイクロアーキテクチャでも対応していない命令があるからです。例えば Pentium ブランドの Clarkdale は SSE4 や AES-NI をサポートしませんし、Pentium ブランドの Sandy Bridge は AVX をサポートしません。あと、マイクロアーキテクチャを判定するのはサポートされる命令を判定するのと比べて単純ではありませんし、ルーチンを追加しなくても新しいマイクロアーキテクチャが出るたびに追従し続けなければいけません。

一番「間違いが無い」のはインストール時にベンチマークを取ってそれを基準にするという方法なのですが、どういう状態になってるのか分からないユーザー環境で取ったベンチマークが信用に値するのかという問題があります。正しくベンチマークを取るにはそれ相応の環境構築が必要です。

で、ここまで考えたわけですが、私はカーズほど頭は良くないし何よりも面倒くさがりなので、早々に考えるのをやめることにしました。AVX が使える世代なら遅いってことはないだろうということで、Sandy Bridge 以降を対象にすることにしました。つまり、(Penryn はともかく) Nehalem で高速化される可能性は捨てていることになります。これが技術的に筋がいいかは疑問が残りますが、実際に AVX 命令を使っている分 SSE4.1 で実行できる扱いにするよりはマシです。ああ、もちろんこの判断は Bulldozer/Piledriver を考慮していないわけですが(そもそも持ってないし近所にベンチマーク環境が無い)。

どうしたもんですかね。


ちなみに、推奨環境を Penryn 以降に変更して Conroe のことは忘れる、という技術的でない解決(というか回避)方法も考えられますが、Conroe を捨てるのは時期尚早な気がします。あと、捨てるなら捨てるで、おそらく Sandy Bridge 以前(つまり AVX が使えない CPU)をまとめて捨てることになるでしょう。3オペランド命令最高。

Trackback

no comment untill now

Add your comment now