QSVEncの速度について考える

ヱヴァQ、「いろいろまじびっくりした」とだけ書いとくです。ええ。



さて。

QSVEncの速度について、いろいろ考えたこと・検証したことを書いておく。

一応、QSVEncの強いメモリ速度依存性で、メモリ速度が最終的に結構効いてくるよ~みたいな話はしたので、速度が気になる人はそっちも見てみてくれるといいかも。

で、この記事は、QSVEncのもっといろんな条件・環境についても考える…かも。今回の話はちょっと長め。

話が長いので、とりあえずどんな話をするかというと、

・QSVEnc実行時の処理の流れ

・デコードのみの速度との比較とそこからわかること

・QSVEnc実行中のCPU使用率

の3つ。



QSVEnc実行時の処理の流れ



まず、QSVEnc実行中の処理の流れがどうなっているか。

おおまかにはこんな感じ。

qsvenc_process

前も言ったけど、実線を追えば処理の流れがわかる。破線も含めてループを追えば、おおまかにどういったループが動いてるかがわかる、まあそういう図。わかりにくかったらすんません。

まあざっくり言えば、デコード→フィルタ→エンコードの順に順次処理されていく。QSVEnc実行中は図のように、
①Aviutlのメインループ
②デコーダのループ
③QSVEncのエンコードループ

の3つのループが同時に動いている。これはマルチコアCPUを効果的に使うため、タスクを並列化させる工夫だけど、基本的には同時に動き続けなかればならないため、どこか遅いループがあればそれに引き摺られて全体が遅くなってしまう。

この図を見ながら、ボトルネックとなりそうなところを考える。

・エンコード部
重要なのは、
- Sandy (Core ix 2xxx) か、Ivy (Core ix 3xxx)か
- HD Graphicsの種類 (HD Graphics 2000, 2500, 3000, 4000)
- GPU Boost

GPU・QSVの速度の問題。QSVのH.264エンコードは、すべてがハードウェアで実装されているわけではなく、一部はGPUの実行ユニットを使う。なので、GPUの速度がエンコード速度に影響してくる。SandyのGPUに比べれば、IvyのGPUは当然速いし、HD2500に比べれば、HD4000のほうが速い。そしてGPU Boostがかからない状況ではやはりエンコード速度が伸びない、ということになってしまう。

・フィルタ部
Aviutlのフィルタ群には重いものも軽いものもあるけど、当然なにもしないほうが速い。重いフィルタを使用すれば当然それで速度は決まってしまう。CPU速度も重要。

・デコード部
フィルタをなしにしたとすると、次にここが問題になる。デコードの速度が上がるよう設定する、高速なデコーダを使う、など。当然CPU速度も影響する。

・ディスクアクセス
これはどうしようもないし、通常は多少影響はするけど、それほどでもない。(ただし、可逆圧縮が入力の場合は相当影響すると思う。)RamDiskとかを使う手もあるけど、入力ファイルをすべてRamDiskに置くのは容量的に厳しいと思う。

フィルタをひとまずなしにして、デコーダの種類・設定を見直し、GPU Boostがかかればそこそこの速度は出るんじゃないかな、と思う。

基本的に、QSVEncは画質はイマイチなので、個人的にはカット編集ぐらいしかせず、フィルタはなしのままさくっとあまり画質を気にしない実写系動画をエンコードする用途に使っている。(アニメはx264で)

もちろんフィルタをかけるのもありだと思うけど、その場合は速度は妥協する、ということで。



デコードのみの速度との比較



次に、デコードのみの速度との比較して、Aviutlのフィルタなしでどこまで速度を伸ばせるかなどを考えていく。

というわけで、検証環境。
Win7 x64
Intel Core i7 3770K (4C/8T @ 3.9GHz)
Intel HD Graphics 4000 (1150MHz)
DDR3-2133 Dual-Channel 16GB (G.Skill F3-2133C9Q-16GAB)
ASUS P8Z77-M
Aviutl 0.99m
QSVEnc 0.12
lsmashinput(rev365)(POP氏ビルド)
m2v.aui (0.7.5a)
m2v.auiは設定に注意する。

入力ファイル
MPEG2 1440x1080i 29.97fps (m2v.aui / lsmashinput.aui)

まあDDR3-2133はチートっぽいですが許してくださいな。

で、QSVEncの速度を測る前に、デコード速度を確認する。上の環境で、Aviutlのフィルタは一切使用せず、色変換はデフォルトのBT.601のまま。測定にはChikuzen氏のAviutl Benchmark pluginを使用し、デコードのみの速度を測る。

これはさっきの図から③エンコードループを取り去って、①メインループと②デコードループだけを回していることになる。まあ要するに、①②ループの最大速度を測ることになる。

m2v.aui      249.5fps
lsmashinput.aui 524.6fps

こんな感じでそれなりに差があるけど、これはlsmashinput(libavcodec)のMPEG2デコーダがマルチスレッドなことが大きい。(m2v.auiはシングルスレッドの模様。)

で次に、実際にQSVEncでエンコードをしてみる。
CQP 24:26:27, 1440x1080i, tff のインタレ保持エンコード。

デコードのみとQSVEnc時とを比較すると、
qsvenc_speed

lsmashinput, m2v.auiともにデコードのみの時と比べて速度がかなり落ちてしまう。

エンコードが加わると遅くなるということは、エンコードループが遅いことが原因だと普通なら考えられる。実際に測定してみると、GPU Boostがかかっていない状態ではそのとおりでエンコードループが遅いため全体の足をひっぱる。しかし、GPU Boostがかかっている場合には、メインループのほうが遅くなっていて、エンコードループ側が①メインループを待っている状態にある。

まあ、GPU使用率にもまだ余裕があるし。
qsv_gpu

①メインループと③エンコードループは並列に動作できるから、どちらも高速に回っても良いはず…なのだが。

デコードのみの時は高速だった①メインループが実際のエンコード時には遅くなってしまうのは、エンコードによってメモリアクセスが増大するからだと思う。以前書いたように(QSVEncの強いメモリ速度依存性)、QSVエンコ時にはどうやらGPUなどが相当なメモリアクセスを行うようだ。一方で、メインループはyv12→yuy2→yc48→yuy2→nv12と色変換を繰り返すため、こちらも相当大規模なメモリアクセスを行う。これらが競合しあって全体的に速度が低下してるんじゃないかな、と思う。

で、その結果としてややlsmashinput.auiのほうが高速なものの、m2v.auiとさほど差はないという結果になった。lsmashinput.auiとm2v.auiだと必要な前処理が変わってきたり、fawとの兼ね合いもあるので、まあ好きな方を使えば良い、ということに。

なんか前はもうちょっと差が出たんだけどな…。あれはインタレ保持じゃないからもっと速度が出るからかな。



QSVEnc中のCPU使用率



さらに、QSVEnc中のCPU使用率を見ていく。デコードはlsmashinput.aui。

lsmashinput_qsv_benchmark_03

まず速度は171.49fps。

lsmashinput_qsv_benchmark_01

CPU使用率がわりと高い…意外とQSVEnc中はCPUを喰う。Aviutlのフィルタはなしなのに…。4C/8Tの3770Kであっても30%前後喰っている。その内訳をProcessHackerで見てみると、こんな感じ。

qsvenc_cpu_threads_01

Aviutlのサブスレッド群が意外とCPUを使用している。これは、(フィルタ無しの時は)単に色変換(YUY2->YC48 / YC48->YUY2)を行なっている部分になる。さっき書いたように、通常時はともかく、QSVEnc使用時のようなメモリアクセスが相当頻発している状況では、マルチスレッドでの色変換は逆効果になりかねない。

というのも、こちらにIvyBridgeのメモリアクセスの速度(RMMTベンチマーク)が載っているけど、メモリアクセスではスレッド数を増やしても大きな速度の向上はなく、むしろIvyBridgeでは書き込みに関してはシングルスレッドが一番速いらしいのだ。

そこで、シングルスレッドで色空間変換(YUY2→YC48 / YC48→YUY2)を行うという、nilpo氏による色変換プラグインを使用してみる。色空間は無変換だけど、解像度を変えたりはしないので、あまり気にしない事にする。

先ほどと同じ設定で、色変換のところだけ、入力・出力共に「BT.601」から「無変換」に変更する。

その結果。

lsmashinput_qsv_st_benchmark_03

183.18fps。少し速くなった。

lsmashinput_qsv_st_benchmark_01

CPU使用率は20%前後に。

スレッドの様子をまたProcessHackerで見てみると、

qsvenc_cpu_threads_02

Aviutlのサブスレッドが完全に沈黙し、メインスレッドの活動率が高まっている。

メモリアクセスでCPUが「待っている」時間はCPU使用率に含まれる。なので、CPU使用率が高いということは必ずしも処理速度が速いという事にはならない。(もちろん一般的にはCPU使用率が高いほうが高速だけど、例外もある)



まとめとか



たいていQSVEncの速度は、ボトルネックになりうる、
・デコード
・フィルタ
・色変換(シングルスレッドのほうがいい?)
・エンコード (GPU速度、GPU Boost)
などのどこかで決まると思う。結構デコードや色変換などでCPUも使うから、いくらなんでもCore i3(物理2コア)ではそんなに速度が出ないだろうと思う。ハードウェア回路といっても、CPU・GPUが高速であるに越したことはない。

そして、上のボトルネックをクリアしたなら、最後のボトルネックとしてメモリ速度が効いてくる。それもわりと…。(もちろんそれ以外にボトルネックがあればあんまり関係ない)

ただ、正直普通のメモリ(DDR3-1600とか)が相当安いだけに、高速メモリはかなり割高なので、コストパフォーマンスが悪すぎるのは確か…。まあそもそもメモリ速くしてもx264はそんなに速くなんないので、QSVのためだけにメモリ買うというのも微妙な話だと思う。



もっと高速なQSVってなんなんだ



fullHDを300fps以上の速度でエンコードできるソフトは、おそらくデコードからエンコードまで一貫してGPU・QSVで行い、デコード結果をCPU側に戻したりしないのだと思う。そうすれば、CPUメモリからGPUメモリへのコピーなども不要になるので、結構速くなるんじゃないかな…と。

まあQSVEncでは構造的に無理ですが。
スポンサーサイト



コメントの投稿

非公開コメント

yuy2

Media SDKを見てるとyuy2をそのまま食わせることが出来るのかな?
と思ったのですが、あまり変換速度には影響しないでしょうか?

Re: yuy2

おっしゃるとおり、yuy2をそのまま渡しIntel Media SDKのほうで色変換させることもできますが、それをすると現状ではやや遅くなってしまいます。

このへんにはプロフラムの構造上の事情も絡んでまして、yuy2で渡すにしろnv12で渡すにしろ、Aviutlからもらったフレームデータを一度Intel Media SDKのほうで用意されるバッファにコピーする必要があります。そして、どうせコピーが必要なら、このメモリコピーついでにyuy2→nv12変換をこちらで行ってしまったほうが速い、ということになるようです。

No title

遅くなってしまうんですね!納得しました
レスありがとうございました

sample_multi_transcode

Intel Media SDKに入っているsample_multi_transcodeを元に改造すれば、まだ、高速化が可能なのでしょうか?

Re: sample_multi_transcode

sample_multi_transcodeからの改造は、Aviutlの出力プラグインであるQSVEnc.auoとしては難しいです。

sample_multi_transcodeは、デコードからフィルタ処理、エンコードに至る全行程をQSVで行うもので、たしかに速度は出ると思います。売り物のエンコソフトでQSVエンコでめちゃくちゃ速いのも、そういうふうに実装しているはずです。

ただ、Aviutlで編集などを行う以上、デコード部は入力プラグインに、エンコード部は出力プラグインに分ける必要があります。そのため、全行程をQSVで行うということは困難です。一度フィルタなどをかけたりするためにCPU側に制御を戻す場合には、どうしても遅くなります(CPU-GPU間のメモリ転送が遅いのでしょうか?)。

QSVEncのさらなる高速化という点では、もっとチューニングするか(もう結構やったつもりですが)、ハードウェアの進化を待つか、といった感じでしょうか。

最適化の記事

もう、かなり最適化されているのであまり意味はないかもしれませんが
ご存知でなければ見てみてはどうでしょうか。
GPUのステージを可視化できるのが面白かったので。

インテル® クイック・シンク・ビデオのパフォーマンスの最適化
http://www.isus.jp/article/quicksyncvideo/qsv-1/
http://www.isus.jp/article/quicksyncvideo/qsv-2/
http://www.isus.jp/article/quicksyncvideo/qsv-3/

Re: 最適化の記事

そう、このIntel GPA 結構面白かったんですけど、最近のGPAにはこのQSV可視化機能がなくなってしまっているみたいで…。
プロフィール

rigaya

Author:rigaya
アニメとか見たり、エンコードしたり。
連絡先: rigaya34589@live.jp
github twitter

最新記事
最新コメント
カテゴリ
月別アーカイブ
カウンター
検索フォーム
いろいろ
公開中のAviutlプラグインとかのダウンロード

○Aviutl 出力プラグイン
x264guiEx 3.xx
- x264を使用したH264出力
- x264guiExの導入紹介動画>
- x264guiExの導入
- x264guiExのエラーと対処方法>
- x264.exeはこちら>

x265guiEx
- x265を使用したH.265/HEVC出力
- x265guiExの導入>
- x265.exeはこちら>

QSVEnc + QSVEncC
- QuickSyncVideoによるHWエンコード
- QSVEnc 導入/使用方法>
- QSVEncCオプション一覧>

NVEnc + NVEncC
- NVIDIAのNVEncによるHWエンコード
- NVEnc 導入/使用方法>
- NVEncCオプション一覧>

VCEEnc + VCEEncC
- AMDのVCE/VCNによるHWエンコード
- VCEEnc 導入/使用方法>
- VCEEncCオプション一覧>

svtAV1guiEx
- SVT-AV1によるAV1出力
- svtAV1guiExの導入>
- SVT-AV1単体はこちら>

VVenCguiEx
- VVenCによるVVC出力
- VVenCguiExの導入>

ffmpegOut
- ffmpegを使用した出力
- ffmpegOutの導入>


○Aviutl フィルタプラグイン
自動フィールドシフト (ミラー)
- SSE2~AVX512による高速化版
- オリジナル: aji様

clfilters 
- OpenCLベースの複数のGPUフィルタ集
- 対応フィルタの一覧等はこちら

エッジレベル調整MT (ミラー)
- エッジレベル調整の並列化/高速化
- SSE2~AVX512対応
- オリジナル: まじぽか太郎様

バンディング低減MT (ミラー)
- SSE2~AVX512による高速化版
- オリジナル: まじぽか太郎様

PMD_MT
- SSE2~AVX512による高速化版
- オリジナル: スレ48≫989氏

透過性ロゴ (ミラー)
- SSE2~FMA3によるSIMD版
- オリジナル: MakKi氏

AviutlColor (ミラー)
- BT.2020nc向け色変換プラグイン
- BT.709/BT.601向けも同梱

○その他
Amatsukaze改造版
- AmatsukazeのAV1対応版

x264afs (ミラー)
- x264のafs対応版

aui_indexer (ミラー使い方>)
- lsmashinput.aui/m2v.auiの
 インデックス事前・一括生成

auc_export (ミラー使い方>)
- Aviutl Controlの
 エクスポートプラグイン版
 エクスポートをコマンドから

aup_reseter (ミラー)
- aupプロジェクトファイルの
 終了フラグを一括リセット

CheckBitrate (ミラー, 使い方, ソース)
- ビットレート分布の分析(HEVC対応)

チャプター変換 (使い方>)
- nero/appleチャプター形式変換

エッジレベル調整 (avisynth)
- Avisynth用エッジレベル調整

メモリ・キャッシュ速度測定
- スレッド数を変えて測定
- これまでの測定結果はこちら

○ビルドしたものとか
L-SMASH (ミラー)
x264 (ミラー)
x265 (ミラー)
SVT-AV1 (ミラー)

○その他
サンプル動画
その他

○読みもの (ミラー)
Aviutl/x264guiExの色変換
動画関連ダウンロードリンク集
簡易インストーラの概要

○更新停止・公開終了
改造版x264gui
x264guiEx 0.xx
RSSリンクの表示
リンク
QRコード
QR