NVEncにバンディング低減を追加 (CUDA)

NVEnc 3.13 English version of changelog

PascalではNVENCが10bit深度とかyuv444などでのエンコードに対応していて、それなりの速度でエンコードできるので、バンディング低減もできるといいかなあ、ということでCUDAで追加してみた。

GTX1060ぐらいでも、かなり速い。


更新内容



[共通]
・バンディング低減フィルタを追加。
・パフォーマンス分析(--vpp-perf-monitor)ができなくなっていたのを修正。


[NVEncC]
・--avcuvidを使用すると、--cropが正しく反映されない場合があったのを修正。



NVEncにバンディング低減 (CUDA)



以前、AVX2とかを使って高速化したものをCUDAを使ってNVEncで再現してみた。

パラメータは、Aviutl版とおなじようにできるようにしたつもり。NVEnc.auoでは「フィルタ/その他」から、NVEncCではコマンド(--vpp-deband)で指定できる。



NVEnc.auo




NVEncC

--vpp-deband [<param1>=<value>][,<param2>=<value>][...]

パラメータ
range=<int> (default=15, 0-127)
  ぼかす範囲です。この範囲内の近傍画素からサンプルを取り、ブラー処理を行います。

mode=<int> (default=1, 0-2)
  設定値:0
  周辺1画素を参照し、元の画素値を維持したまま処理を行います。

  設定値:1
  周辺1画素とその点対称画素の計2画素を参照し、ブラー処理を行います。

  設定値:2
  周辺2画素とその点対称画素の計4画素を参照し、ブラー処理を行います。

thre=<int> (一括設定)
thre_y=<int> (default=15, 0-31)
thre_cb=<int> (default=15, 0-31)
thre_cr=<int> (default=15, 0-31)
  y,cb,cr 各成分の閾値です。この値が高いと階調飛びを減らす一方で、細かい線などが潰れます。

dither=<int> (一括設定)
dither_y=<int> (default=15, 0-31)
dither_c=<int> (default=15, 0-31)
 y, cb & crのディザの強さ。

seed=<int>
 乱数シードの変更 (default=1234)

blurfirst (default=off)
ブラー処理を先にすることでディザ強度を減らしつつ、階調飛びが多い素材での効果を上げます。
全体的に副作用が強くなり細かい線が潰れやすくなります。

rand_each_frame (default=off)
  毎フレームシード値を変更します。

例: --vpp-deband range=31,dither=12,rand_each_frame



効果



入力がまあこんな感じだとして…



ややrangeを広めにかけるとこのぐらい (--vpp-deband range=31,dither=12,rand_each_frame)



まあ、強すぎとか弱すぎとかはひとそれぞれだろうし、出力が8bitで圧縮率を高めにすると再発しちゃったりするけど、それなりにちゃんと効果はあるみたい。



処理速度



環境
i7 5960X 8C/16T
Core 3.9GHz / Uncore 3.6GHz
DDR4-2666, 4ch, 32GB
GTX1060 + 382.33ドライバ

測定
--vpp-perf-monitor

fullHDを1枚処理する平均速度 (206フレームの平均)
パラメータは乱数生成の有無を除きデフォルト

毎フレーム乱数生成
なしあり
yuv4208bit196.8 us374.3 us
10bit243.3 us454.4 us
yuv4448bit350.9 us540.3 us
10bit437.8 us655.5 us


そのほかのCUDAフィルタの速度 (リンク先はすべてyuv420 8bitの結果)



とまあ、前にやったAviutlでのAVX2版とかと比べても、だいぶ速いなあ、という感じ。

AviutlのYC48はデータサイズでいうとyuv444 10bitと同じpixelあたり6byteなのだけど、fullHDのYC48に対して5960X 8C/16T @ 4.2GHzが1.51ms、一方今回のが乱数生成なしで437.8us = 0.44msなので、まあ3倍以上速い。

CUDAは、処理対象のデータ構造が比較的単純であれば、とりあえずGPUで動くだけのコードはわりとあっさり書けるので、そういう意味ではSIMDよりかは楽な場合もある。CUDAが辛くなってくるのは、以下のような場合。

・そもそも並列度の低い計算には向かない
・レジスタスピルすると性能がガタ落ちする(cc3.x/5.xでだいぶ起こりにくくなったけど)
・処理ループが長く分割しにくいとかFP64とかだとレジスタを使いまくって詰む
・クラスとかポインタを駆使した複雑なデータ構造には向かない
→ (Unified Memory使うしかない)
・CPUとGPUの間でそれなりのサイズのデータをやりとりしようとした瞬間、
 異常に遅くなる (PCIe実効帯域でない)
・これを解決しようとすると、pinnedメモリとかstreamとかeventとか
 使い始めて異常に面倒なコードになる
・総和演算がどう見ても黒魔術 (やってることはわかるんだけど…)

これ、ひとつも当てはまらないようにするのは結構難しいかもだけど、幸いにしてNVEncのフィルタ処理だと、このいずれにも当てはまらないので、比較的楽だったりする。まあでもとりあえずはざっと、

・テクスチャキャッシュを使う
バンディング低減はランダムアクセスを大量にするのだけど、この速度を改善してくれる。

・ブロックサイズ調整
CUDAはブロック単位でSMに投入されるので、このブロックに入れるスレッド数が結構重要だったりする。メモリアクセスパターンと並列数とかを考えながら、手探りでチューニング。それなりに速度が変わる。

・なるべくFP32演算
GPUはIntよりFP32のほうが速いらしい。

・条件分岐はtemplateでコンパイル時に削除
GPUの条件分岐は、ようはSIMDでいうマスクなので分岐の両方の時間がかかるので、なくせるならなくしてしまう。欠点は、バイナリサイズが増えること…。

・#pragma unroll
GPUは、CPUならSIMD演算の合間にOoOでやってくれるちょっとした処理でも遅くなる。つまり、ループ処理自体も遅いので、展開してあげたほうが速くなることが多い。さらにループを展開することで定数にできる変数もあったりすると、そのぶん演算量が減るのでさらにおいしい。欠点は、バイナリサイズが増えること…。

・乱数はcurandのデバイスAPI
curandは結構お手軽に使えてなかなか便利。xorwowというのが一番速いらしいのでそれで。さすがにメルセンヌツイスターとかでなくてもいいと思う。

とかで、そんなにきっちりチューニングはしてないけど、ある程度の速さは出ていると思う。



ダウンロード>>
ダウンロード (ミラー) >>
OneDriveの調子がいまいちの時はミラー(GDrive)からどうぞ。同じものです。

ソースはこちら>>


スポンサーサイト

コメントの投稿

非公開コメント

No title

些細な点ですが、NVEncC v3.13で -hでヘルプを出力した時、
--bframesの説明が
 x86版:Default: H.264 - 2959664 frames, HEVC - 3 frames
 x64版:Default: H.264 - 41756064 frames, HEVC - 3 frames
と何か変な数字になってしまっているようです。

Re: No title

ありがとうございます。次回修正します。

No title

いつもお世話になっております。
NVEncCでバンディング低減をしようとしたのですが
速度がそんなに変わらなかったです・・・
一番最速だと思われるコマンドを教えて下さいませ。

Re: No title

そんなに変わらない、というのは何と比べてらっしゃるのでしょうか…。

ちなみに手元のGTX1060ではこんな感じです。

x64\NVEncC64.exe -i sample_movie_1080p.mpg -o S:\test.mp4 --vpp-deband


NVEncC (x64) 3.13 (r532) by rigaya, Jun 24 2017 21:37:56 (VC 1900/Win/avx2)
NVENC API v8.0
OS Version Windows 10 x64 (15063)
CPU Intel Core i7-5960X @ 3.00GHz [TB: 3.90GHz] (8C/16T)
GPU #0: GeForce GTX 1060 6GB (10 EU) @ 1708 MHz (382.33)
Input Buffers CUDA, 32 frames
Input Info avcuvid: MPEG2, 1920x1080, 30000/1001 fps
Vpp Filters cspconv(nv12 -> yv12)
deband: mode 1, range 15, threY 15, threCb 15, threCr 15
ditherY 15, ditherC 15, blurFirst no, randEachFrame no
cspconv(yv12 -> nv12)
Output Info H.264/AVC high @ Level auto
1920x1080p 1:1 29.970fps (30000/1001fps)
avwriter: h264 => mp4
Encoder Preset default
Rate Control CQP I:20 P:23 B:25
Lookahead off
GOP length 300 frames
B frames 3 frames
Ref frames 3 frames, LTR: off
AQ off
Others mv:auto cabac deblock adapt-transform:auto bdirect:auto


encoded 5204 frames, 322.97 fps, 18532.15 kbps, 383.61 MB
encode time 0:00:16, CPU: 6.42%, GPU: 12.85%, VE: 89.10%, GPUClockAvg: 1844MHz
frame type IDR 18
frame type I 18, avgQP 20.00, total size 6.03 MB
frame type P 1301, avgQP 23.00, total size 160.48 MB
frame type B 3885, avgQP 25.00, total size 217.09 MB

No title

速度が変わらないというのは
NVEncCでバンディング低減のコマンドを入れたのと入れなかったのとの速度の差です。
紛らわしくてすみません

Re: No title

バンディング低減を入れても入れなくても速度が変わらないというのは、多くのGPUではそうなるかと思いますが…。

エンコードのほうが遅いので、バンディング低減の処理をしてもしなくても速度は変わらない事が多いかと思います。
プロフィール

rigaya

Author:rigaya
アニメとか見たり、エンコードしたり。
連絡先(@を半角にしてください!)
rigaya34589@live.jp
github

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

○Aviutlプラグイン
x264guiEx 2.xx (ミラー)
- x264を使用したH264出力
- x264guiExの導入>
- x264.exeはこちら>

x265guiEx (ミラー)
- x265を使用したH.265/HEVC出力
- x265.exeはこちら>

QSVEnc + QSVEncC (ミラー)
- QuickSyncVideoによるH264出力
- QSVEncCはコマンドライン版
- QSVEncC 導入/使用方法>
- QSVEncCオプション一覧>

NVEnc + NVEncC (ミラー)
- NVIDIAのNVEncによるH264出力
- NVEncCオプション一覧>

VCEEnc + VCEEncC (ミラー)
- AMDのVCEによるH.264出力

ffmpegOut (ミラー)
- ffmpeg/avconvを使用した出力

自動フィールドシフト (ミラー)
- SSE2~AVX2による高速化版
- オリジナル: aji様

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

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

PMD_MT (ミラー)
- SSE2~FMA3による高速化版
- オリジナル: スレ48≫989氏

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

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

○その他
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 (ミラー)

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

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

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