UtVideo のハフマン符号ルーチンは1つの符号ストリームを直列に処理しているだけで、1つのシンボルの処理を完了させないと次のシンボルを処理できず、プロセッサの実行ユニットを休みなく働かせることができません。HT 環境では2つのスレッドで別々のストリームを処理することで実行ユニットの稼働率を上げられますが、Eコアだと HT はありませんし、Pコアも Arrow Lake では HT が有効ではありません。

他のハフマン符号を使ったアプリケーションでは、1スレッド内で複数の符号ストリームを並行して処理することでこの問題に対処することがあります。例えば Zstandard の中にあるハフマン符号実装では4つ並行して処理するようになっています。

UtVideo ではハフマン符号ルーチンはアセンブリ言語で書いていて、レジスタ割り当てを検討したところ2ストリームならなんとか行けそうに思えました。しかし、複数ストリームを並行して処理しようとするとプログラムが読みづらくなります。というわけでアセンブリ言語で書いた1ストリーム版を一旦そのまま C++ で置き換えたようなものをコンパイルしたのですが、そうすると元のプログラムより速くなります。ただ、出力されたバイナリを眺めていて得られた知見をアセンブリ言語の方に適用すると、やっぱりアセンブリ言語の方が速くなりました。これが UtVideo 23.2.0 で今更になってまだ高速化された経緯です。

なお、以前 AVX-512 を使った複数ストリーム並列処理を試してみたことはありますが、書いてある通り AVX-512 が必須ですし、大量の計算資源を投入しても大して速くならず、効率が非常に悪い上に扱いが難しいのでこれを使うことはないでしょう。

というわけで、並行に処理する実装に挑戦しても、どうやらアセンブラからは離れられないようです。コンパイラはもうちょっと頑張ってほしい。

Trackback

no comment untill now

Add your comment now