Ut Video Codec Suite で Halide を使う前提で遊んでみましたが、この前提に立つ限り Halide は使い物にならないように見えます。

まず前の記事で書いた通り、 UMxx の処理 (8SymPack) はそもそも Halide で記述できなさそうです。ダメそうだと思いつつも StackOverflow で聞いてみましたが解答は付きませんでした。この時点で半分ぐらいのルーチンは Halide では書けないことになります。

次に、ULxx で使っているフレーム内予測のうち predict left を記述してみます。非常に単純な処理なので本質的な部分は1行で書けます。

Func predict_left;
Var x;
ImageParam input(type_of<uint8_t>(), 1);
Func input_ = BoundaryConditions::constant_exterior(input, (uint8_t)0x80);
predict_left(x) = input_(x) - input_(x-1);
predict_left.vectorize(x, 16);

UtVideo にある intrinsic 版(正確にはヒストグラムを取る処理を取り除いたもの)と速度を比較したところ、Halide が吐いたバイナリの方が1-2%ほど速いという結果になりました。これだけ単純な処理内容であるにもかかわらず Halide が吐いたバイナリを読んでも何が書いてあるのかサッパリ分からないのですが、確かに何度計測してもちゃんと速く動きます。

次にこの逆の処理である restore left を記述してみます。これまた単純な処理ですが、predict の方ほどは単純ではなく、 RDom が登場します。

Func restore_left;
Var x;
ImageParam input(type_of<uint8_t>(), 1);
restore_left(x) = input(0) + (uint8_t)0x80;
RDom r(1, input.width()-1);
restore_left(r) = input(r) + restore_left(r-1);
restore_left.vectorize(x, 32);

で、対応する intrinsic 版と速度を比較しましたが、Halide の方が3倍以上時間がかかります。試しにベクトル化もループアンローリングも全くしていないものを C で書いてみたところ Halide よりちょっと遅いぐらいだったので、 Halide はロクにベクトル化できていないことが分かります。

restore left すらうまく扱えないようでは使い物にならないので、現状 Halide を UtVideo に適用するのは時期尚早のようです。Halide を使うことで処理の fusion を簡単に扱えるようになることを期待していたのですが、諦めて intrinsic で書くことにします。

Trackback

no comment untill now

Add your comment now