Ut Video Codec Suite 高速化の11年

Slides:



Advertisements
Similar presentations
1 広島大学 理学研究科 尾崎 裕介 石川 健一. 1. Graphic Processing Unit (GPU) とは? 2. Nvidia CUDA programming model 3. GPU の高速化 4. QCD with CUDA 5. 結果 6. まとめ 2.
Advertisements

G ゼミ 2010/5/14 渡辺健人. パフォーマンスの測定 CUDA Visual Profiler CUDA の SDK に標準でついているパフォーマン ス測定用のツール 使い方: exe ファイルのパスと作業ディレクトリ指定して実 行するだけ 注意点 : GPU のコード実行後にプログラム終了前に,
JT-H 265(第 1 版) 高効率ビデオ符号化方式 HIGH EFFICIENCY VIDEO CODING メディア符号化専門委員会 JT- H 265第 1.0 版 OHP- 1.
データの圧縮.
「AMDで使うと遅いんだけど」 x86/x64最適化勉強会 #4 LT
Motion-JPEG2000を使ったノードに最適な動画像配信
連続系アルゴリズム演習 第2回 OpenMPによる課題.
計算理工学基礎 「ハイパフォーマンスコンピューティングの基礎」
CPUについて HN:セシル.
Chapter11-4(前半) 加藤健.
Ibaraki Univ. Dept of Electrical & Electronic Eng.
Intel AVX命令を用いた並列FFTの実現と評価
最新ファイルの提供を保証する代理FTPサーバの開発
富山大学 公開講座 2008 「QRコードを作ろう!」 ~ QRコードを作ろう! ~.
Webアプリケーション開発の 基本的なポイント
LZ圧縮回路の設計とハード・ソフト 最適分割の検討 電子情報デザイン学科 高性能計算研究室 4回生 中山 和也 2009/2/27.
Xenを用いたクラウドコンピュー ティングにおける情報漏洩の防止
情報理工学部 情報システム工学科 ラシキアゼミ3年 H 岡田 貴大
実行時のメモリ構造(1) Jasminの基礎とフレーム内動作
神奈川大学大学院工学研究科 電気電子情報工学専攻
読んだもの1 P0145R1: Refining Expression Evaluation Order for Idiomatic C++
全体ミーティング (6/13) 村田雅之.
応用情報処理V 第1回 プログラミングとは何か 2004年9月27日.
心理学情報処理法Ⅰ コンピュータにおけるデータ表現 マルチメディアとコンピュータ.
2007/1/18 山下 諒蔵 佐藤 春旗 前田 俊行 大山 恵弘 佐藤 秀明 住井 英二郎
2012年度 情報数理 ~ QRコードを作ろう!(1) ~.
2008年度 情報数理 ~ QRコードを作ろう!(1) ~.
日本大学 文理学部 情報システム解析学科 谷研究室 益田真太郎
第7章 データベース管理システム 7.1 データベース管理システムの概要 7.2 データベースの格納方式 7.3 問合せ処理.
応用情報処理V 第1回 プログラミングとは何か 2003年9月29日.
プログラムはなぜ動くのか.
オペレーティングシステム i386アーキテクチャ(2)
発表者 2011/01/08 楽しい256バイトイントロの 世界 発表者 2011/01/08.
最短路問題のための LMS(Levelwise Mesh Sparsification)
コンテンツ配信 エンコード (符号化) CBR (Constant Bit Rate) VBR (Variable Bit Rate)
IIR輪講復習 #5 Index compression
2010年度 情報数理 ~ QRコードを作ろう!(1) ~.
オーサリングツール&ブラウザの 技術的トピック
型付きアセンブリ言語を用いた安全なカーネル拡張
SpectreとMeltdown ITソリューション塾・第28期 2018年5月30日 株式会社アプライド・マーケティング 大越 章司
CPUの仕組み 1E16M002-5 阿部知也 1E16M007-3 伊藤達哉 1E16M026-9 小島祥太郎 1E16M069-8 峰晴晃優 1E16M070-0 宮路暁久 1E14M070-5 南元喜.
コンピュータを知る 1E16M009-1 梅津たくみ 1E16M017-8 小沢あきら 1E16M035-0 柴田かいと
動画ファイル形式 コンピュータでは、文字や画像、動画、音声といった様々な種類の情報を扱うことができるが、記憶装置に記録されるデータそのものは0と1の情報でしかない。動画ファイルの形式としてはMPEGやAVIです。
澤見研究室 I04I021 片山祐輔 I05I095 山田大志 I06I040 野崎祥志
Ut Video Codec Suite ~ これまで と これから ~
梅澤威志 隣の芝は茶色いか 梅澤威志
コンピュータ系実験Ⅲ 「ワンチップマイコンの応用」 第1週目 アセンブリ言語講座
オペレーティングシステムJ/K (仮想記憶管理)
第7回 授業計画の修正 中間テストの解説・復習 前回の補足(クロックアルゴリズム・PFF) 仮想記憶方式のまとめ 特別課題について
通信機構合わせた最適化をおこなう並列化ンパイラ
動画形式 2010年11月.
先進的計算基盤システムシンポジウム SACSIS2007併設企画 マルチコアプログラミングコンテスト 「Cellスピードチャレンジ2007」
未使用メモリに着目した 複数ホストにまたがる 仮想マシンの高速化
プロジェクト演習Ⅱ インタラクティブゲーム制作
個人の動画配信のためのWebサーバ構築 06A1058 古江 和栄.
様々な情報源(4章).
複数ホストにまたがって動作する仮想マシンの障害対策
VMMのソフトウェア若化を考慮した クラスタ性能の比較
先週の復習: CPU が働く仕組み コンピュータの構造 pp 制御装置+演算装置+レジスタ 制御装置がなければ電卓と同様
動画配信捕捉のためのWEBサーバ構築 06A1058 古江 和栄.
09. メモリ・ディスアンビギュエーション 五島 正裕.
第5回 メモリ管理(2) オーバレイ方式 論理アドレスとプログラムの再配置 静的再配置と動的再配置 仮想記憶とメモリ階層 セグメンテーション
Ibaraki Univ. Dept of Electrical & Electronic Eng.
第4回 メモリ管理 主記憶(メインメモリ)の管理 固定区画方式と可変区画方式 空き領域の管理 スワッピング.
全体ミーティング (5/23) 村田雅之.
Mondriaan Memory Protection の調査
計算機アーキテクチャ1 (計算機構成論(再)) 第二回 命令の種類と形式
SMP/マルチコアに対応した 型付きアセンブリ言語
Ibaraki Univ. Dept of Electrical & Electronic Eng.
コンピュータと音 B3 入野仁志(irino).
Presentation transcript:

Ut Video Codec Suite 高速化の11年 梅澤威志/ゆーむ (twitter: @umezawa_takeshi) IM@S Engineer Talks 2019

自己紹介 梅澤威志 / ゆーむP 本業は某ネット企業の ソフトウェアエンジニア 箱マスからのアイマスP ニコマスも少々 響P Blog: http://umezawa.dyndns.info/wordpress/ GitHub: https://github.com/umezawatakeshi 箱マスからのアイマスP ニコマスも少々 ニコ百: https://dic.nicovideo.jp/a/ゆーむp 響P ぬーかわ

目次 Ut Video Codec Suite is 何 作り始めたきっかけ 圧縮手法 高速化の歴史

Ut Video Codec Suite is 何

Ut Video Codec Suite is 何 映像キャプチャ向け可逆圧縮コーデック 各種プラットフォームで使えた(過去形(涙 http://umezawa.dyndns.info/wordpress/?cat=28 https://github.com/umezawatakeshi/utvideo FFmpeg に互換実装がある

いろんなところで使われている ニコマス方面とか MMD 方面とか ニコニコの コンテンツツリーで 子作品25240 (2019-07-06現在) http://commons.nicovideo.jp/tree/im1922939

いろんなところで使われている (2) 海外に紹介されたり FFmpeg に互換実装が追加されたり D:\ffmpeg-4.1.3-win64-static\bin>ffmpeg.exe -codecs ffmpeg version 4.1.3 Copyright (c) 2000-2019 the FFmpeg developers built with gcc 8.3.1 (GCC) 20190414 (中略) Codecs: D..... = Decoding supported .E.... = Encoding supported ..V... = Video codec ..A... = Audio codec ..S... = Subtitle codec ...I.. = Intra frame-only codec ....L. = Lossy compression .....S = Lossless compression ------- D.VIL. txd Renderware TXD (TeXture Dictionary) image D.V.L. ulti IBM UltiMotion (decoders: ultimotion ) DEVI.S utvideo Ut Video DEVI.S v210 Uncompressed 4:2:2 10-bit D.VI.S v210x Uncompressed 4:2:2 10-bit (以下略)

いろんなところで使われている (3) 映像作品の納品フォーマットとして(伝聞 映像上映イベントの再生フォーマットとして FRENZ というイベントで 2017 年から使われている https://frenz.jp/

作り始めたきっかけ

エースコンバット6をキャプりたかった 2007年にエスコン6のプレイ動画をHD (720p) でキャプりたかった 非圧縮 YUV422 だと 1280x720x2x60=約110MB/s 今なら単発HDDでもこれぐらい出るが当時は無理だった(最外周の一番速いところでも70MB/sぐらい) SSDもまだまだバカ高かった 何らかの圧縮をしてからHDDに保存する必要がある ちなみにできた動画が https://www.nicovideo.jp/watch/sm1770031

Huffyuv 2007年後半、キャプチャ向け映像コーデックとして有力なのは Huffyuv であった HDキャプチャ用途だと以下の問題があった 圧縮比がちょっと足りない 速度がちょっと足りない シングルスレッド MMX 前提(= SSE2 を使っていない)

どう問題になるか 圧縮比があまり高くないので、やっぱり単発HDDでは追いつかないことが時々ある 仕方ないので2台でRAID0していた RAIDしても今度はCPUの処理が追いつかないことが時々ある 定格 2.4GHz の CPU を 3.0GHz まで OC してお茶を濁す

ちかたない 自分に需要がある 自分に作る能力がある 作ることに対する興味がある ので作る 他人にもたぶん需要がある 自分に作る能力がある 作ることに対する興味がある ので作る 年末ごろからどういう方向で作るかを考え始めた(…と記憶している(曖昧

圧縮手法

そもそも論 一般的に映像エンコードはこんな処理をする 左右の画像は http://icooon-mono.com/ より

圧縮手法 大枠としては Huffyuv と変わらない 異なる圧縮原理を考えるような脳みそは無い Huffyuv が(時代背景のせいで)できなかったことをやることによって性能を向上させる 説明(手法の必然性)の理解しやすさの観点から、圧縮の処理順序の逆順で説明する

圧縮手法 – ハフマン符号 エントロピー符号化の一種であるハフマン符号を使って圧縮 Huffyuv では符号語テーブルが画像によらず固定だったので最適な符号化になっておらず圧縮比が低かったが、UtVideo では(ほぼ)正しくハフマン符号を使うので(ほぼ)最適である

圧縮手法 – フレーム内予測 単に画像を直接ハフマン符号化しても小さくならない 近傍のピクセルから値を予測してそれとの差を取り、値をゼロ付近に集めてエントロピー(情報量)を削減すると、圧縮しやすくなる 予測の際は、近傍のピクセルと値が近いことが多い、という性質を利用する

圧縮手法 – フレーム内予測 (2) 予測タイプは現在3種類ある left – 左の値を予測値とする gradient – 左、上、左上の値からなる1次関数で予測値を得る 予測値 = left + top – topleft median – 左、上、 gradient の3つのうちの中央値を予測値とする 予測値 = median(left, top, gradient) UtVideo においては median, left, gradient の順に実装した

圧縮手法 – フレーム内予測 (3) 予測値の計算(と予測値との差の計算)は3種類とも SIMD 化できる ピクセル間に依存関係がないので、ちゃんと要素数分だけ速くなる SIMD (Single Instruction Multiple Data) 複数のデータに対して同一の処理をまとめて行う並列化体系のこと

圧縮手法 – フレーム内予測 (4) 予測の復元(「予測値との差」だけがある状態から元の値を計算する)は、 median の場合 SIMD 化できない 前のピクセルの値が次のピクセルの予測値の計算に使われており、しかも式が線形ではないから gradient と left は線形なので、要素数分とまでは行かないが SIMD 化で速くなる

圧縮手法 – planar 変換 チャンネルごとに分解する(planar変換) 画像は三原色(+アルファチャンネル)から成るが、チャンネルごとに圧縮のしやすさが異なる。 圧縮のしやすさが異なるものは別々に処理した方が効率が良い

唐突に x86 のレジスタ構成 x86 のレジスタはこういう形式でアクセスできるようになっている EBX, ECX, EDX もある (他にもあるけど割愛) EAX に 0x12345678 を入れると、 AX として見ると 0x5678、 AH は 0x56、 AL は 0x78 となる ここで AL に 0x90 を入れると AX は 0x5690 になる

細かいデザイン ハフマン符号化では、シンボルに対する符号語をテーブル参照で取ってきて、シフトしてつなげていく、という処理になる

細かいデザイン ハフマン符号化では、シンボルに対する符号語をテーブル参照で取ってきて、シフトしてつなげていく、という処理になる

細かいデザイン ハフマン符号化では、シンボルに対する符号語をテーブル参照で取ってきて、シフトしてつなげていく、という処理になる

細かいデザイン (2) CL レジスタに符号語長が入ると都合が良い ECX レジスタの上位 24bit が空いてるので符号語を入れる x86 の可変シフト命令ではシフトするビット数を CL レジスタで指定するため ECX レジスタの上位 24bit が空いてるので符号語を入れる 符号語長と符号語を一発で ECX にロードできる

高速化の歴史

1.1.3 (2008-04-18) 最初の public release 予測タイプは median のみ 遅い 合計約2000行

2.1.0 (2008-05-01) スライス方式によりマルチスレッド化した スレッド間の同期処理はほとんどないので単純にコア数分だけの高速化になっている

2.2.0 (2008-05-07) ハフマン符号の符号化/復号化 と フレーム内予測の予測/復元 をアセンブリ言語で書いた 特に、コンパイラが吐いてくれない命令を駆使することで高速化した SHLD – ハフマン符号化/復号化 BSR – ハフマン復号化 CMOVcc – フレーム内予測 これでおおむね Huffyuv と同程度の速度になった

3.3.0 (2008-05-17) 部分レジスタストールを回避するように書き換えて predict median の復元を高速化 長いレジスタ(たとえば EAX)の部分(たとえば AL)を更新した後に、更新した場所以外を含む領域を使おうとすると、部分の更新を一旦全体に結合するためにペナルティがかかる。これを部分レジスタストールという readme によるとハフマン符号等も含めた全体で 20% ほど速くなったらしい(単体だと50%ぐらい?

3.3.0 (2008-05-17) (2) SHLD 命令の使い方が甘かったのを改良してハフマン符号の符号化を高速化 元の符号化のコードは C++ で書いたものをそのままアセンブリ言語で書き直した感じの物で、あまり効率が良くなかった

3.7.0 (2008-06-07) predict median の復元で CMOVcc 命令を駆使する代わりに MMX の PMAX/PMIN 命令を使って高速化 MMX は SIMD 命令セットであるが、この修正では最大値/最小値を一発で計算する命令を単一要素に対して使っている(CMOVcc 命令はそれほど速くない この時の blog に「肝心のハフマンデコードが速くならないのでそろそろ限界が…」とか書いてある

3.8.0 (2008-06-10) ハフマンデコードが速くならないので諦めて predict left フレーム内予測方式を追加 それなりにややこしい処理をする predict median と比べると単純であり、復元がハフマン復号化のついでにできるので圧倒的に高速である(デコードは全体で1.5倍速 代わりに圧縮比は下がる

7.0.0 (2009-10-22) x64 版を追加 ちなみに Windows 7 の発売日あわせである UtVideo のバージョンも 7 なのはたまたま とりあえず全部 C++ で書いてある(昔からある C++ コードが使われる)ので非常に遅い

7.1.0 (2010-04-04) AMD Athlon (K10 マイクロアーキテクチャ)でRGB/RGBA の処理が猛烈に遅い問題の解決 具体的には全体で3倍ぐらい遅かった RGB/RGBA の場合、 planar 変換時に各 plane のポインタが同じ速度で進む 各 plane バッファの先頭アドレスはそれぞれ「キリがいい」ので、各ポインタが常にキャッシュの同じエントリアドレスを指す

7.1.0 (2010-04-04) (2) K10 だと1次キャッシュが 2way セットアソシアティブなので、メモリアクセスするたびにキャッシュがスラッシングして猛烈に遅かった 対策として、最初からずらしておけば、今度は絶対に同じエントリアドレスにはならない https://speakerdeck.com/umezawatakeshi/x86-x64-optimization-study-4-ut-video-codec-suite-is-slow-on-amd-processors を参照

8.2.0 (2010-09-05) 短い符号語の場合にテーブル一発参照方式をとることでハフマン復号化を高速化 以前はデコードテーブルを小さく(約4KB)するためにめんどくさい(=時間のかかる)処理をやっていたが、今時1次キャッシュは32KBあるのでシンプルに行けることに気づいた 全体として20%以上速くなったらしい

8.2.0 (2010-09-05) (2) こんな感じ 符号語長のところに「12bit に収まっていない」と書いてあったら、次のシンボルのデコードは以前と同じ処理にフォールバックする

8.3.0 (2010-10-11) 8.4.0 (2010-10-17) predict left で native なフォーマットへのデコードで、ハフマン復号化の出力を planar 形式を経由せずに直接フレームバッファに書き込むようにして高速化 predict left の場合ハフマン復号化のついでにフレーム内予測の復元をすることが現実的 メモリコピーと変換処理が削減された

8.3.0 (2010-10-11) (2) 8.4.0 (2010-10-17) (2) こんな感じで直接復号化していく

8.5.0 (2010-11-02) ハフマン復号化でループ内のレジスタ間 MOV 命令を1個削減して高速化 命を削ってクロックを削れ! ループが1周10クロックぐらいなので、これだけで10%も速くなる 命を削ってクロックを削れ! あと x64 が x86 と同程度にアセンブラ化された

12.1.0 (2013-04-23) packed <-> planar 変換を SIMD 化して高速化 Sandy Bridge (Core i 2000 series) だとシャッフル命令が十分に速い 2008年ごろは開発マシンに Merom (Core 2 Quad Q6600) を使っており、 シャッフル命令が速くなかったせいで逆に遅くなっていた ちなみにシャッフル命令が「だいぶ速くなった」のは Penryn (Merom の次)である。

12.1.0 (2013-04-23) (2) RGBA の変換の場合、 以前は 64 シンボル処理するのに 64 クロック SIMD 化すると Sandy Bridge で 6 クロック Merom で走らせるとたぶん 24 クロック あれ、なんで遅くなるんだ…?

12.2.0 (2013-05-12) 再び部分レジスタストールを回避してハフマン復号化が高速化 全体で見て5~10%ぐらい 部分レジスタストール怖い

13.2.0 (2013-09-21) x64 で、64bit レジスタを駆使することで SHLD 命令を回避してハフマン復号化を高速化した Haswell マシン (Core i7-4770) を調達したので BMI2 命令 (SHLX, SHRX) を使ってさらに高速化 両方合わせて Haswell なら最大25%高速化

17.2.0 (2016-12-30) ハフマン復号化で、テーブル1回の lookup で複数シンボル同時に出力するようにして劇的に高速化した ハフマン復号化単体で言うと倍ぐらい行ける ただし、復号化のついでに predict left の復元をやることができなくなる(やろうとすると複雑すぎて遅くなる)ので、デコード全体としてはそこまでではない

17.2.0 (2016-12-30) (2) それなりに圧縮できている場合は複数シンボルぶんの符号語が 12bit の中に収まっている可能性が高いので、だったらまとめて処理すれば速い 代わりにデコードテーブルがかなり大きくなった(3倍)

17.2.0 (2016-12-30) (3) こんな感じ この図の例だと 3シンボル同時に 出力される

18.0.0 (2017-04-01) predict gradient フレーム内予測方式を追加 圧縮比が predict left より高めで、かつ SIMD 化のしやすさは left と同程度、といういいことづくめ 圧縮比が高いとメモリアクセス等が減るので、結果的に速くなる 今まで実装を避けていたのを後悔するレベル

18.0.0 (2017-04-01) (2) ハフマン符号化をループアンローリングして高速化 ループ1周が数クロックなので、アンローリングの結果としてループ終了判定が削減されるだけでそれなりに速くなる(そこまで劇的な効果は無かったが このあたりでフルHDの YUV420 クリップのデコードが 1000fps を超えた

20.2.0 (2019-01-14) x64 で、2シンボル同時に符号化することでハフマン符号化を高速化 符号語長は最大24bitであるが、64bitレジスタになら2シンボル分載せることができることを利用する

20.2.0 (2019-01-14) (2) 2シンボルずつ符号化する場合、エンコードテーブルが1次キャッシュ (32KB) どころか2次キャッシュ (256KB) にも収まらない 1シンボルずつなら 8B x 256エントリ = 2KB であるが、 2シンボルずつだと 8B x 64Kエントリ = 512KB 一方、シンボルの出現確率には偏りがあるので、よくアクセスされるのは 256KB の範囲に収まるとみなして構わない

20.2.0 (2019-01-14) (3) 2次キャッシュにおおむね収まるなら、レイテンシの増加による性能劣化を上回って高速化できる 2次キャッシュのレイテンシは1次キャッシュの 3倍であるが、ループアンローリングのついでに先行して符号語をロードすることでレイテンシを完全に隠蔽できる x64 だとレジスタが多いのでこういうことが可能 結果としてハフマン符号化だけを見ると倍速で処理できるようになった

20.3.0 (2019-03-14) 20.5.0 (2019-05-09) 一時バッファとしての planar フォーマットを経由せず、レジスタ上で処理してメモリアクセスを削減することで、特にマルチスレッド時の高速化をした マルチスレッド時はコアの処理速度ではなくメインメモリの帯域で律速しているから 極端な計測条件だと倍速になる

20.3.0 (2019-03-14) (2) 20.5.0 (2019-05-09) (2) 劇的に速くなることは理論的に予想できていたが、ルーチンの種類が爆発的に増えるので避けていた

20.3.0 (2019-03-14) (3) 20.5.0 (2019-05-09) (3) 複数 plane 同時に処理することになるので、ついでに predict median の復元の効率化が図られてそこでも高速化した 同じ plane の前のピクセルには依存関係があるが、異なる plane のピクセルには依存関係がないので並列処理可能

結局どこまで速くなったか 60倍 Core i7-4770 / 8.4.0 までは x86 8.5.0 からは x64 マルチスレッド / predict median / crowd_run 4K

One More Thing… 19.0.0 の時に SIMD にやさしいフォーマットとして UtVideo T2 を 追加した さすがに発表時間が足りないので詳細は割愛

俺たちの最適化はこれからだ! 梅澤先生の 次回作 次バージョンにご期待ください T2 の説明もご期待ください(いつだ