インテル® MSDK 2.0 とインテル® グラフィックス・パフォーマンス・アナライザー(インテル® GPA)4.1
第2世代のインテル® Core™ プロセッサー(Sandy Bridge マイクロアーキテクチャー)以降の内蔵 GPU に搭載されているインテル® クイック・シンク・ビデオを利用すれば、メディアファイルのデコード、エンコードおよびトランスコードが、ハードウェア・アクセラレーションにより高速に実行可能である。
そして、開発環境としては、インテル® メディア SDK 2.0(以下、MSDK と呼ぶ)が、このハードウェア・アクセラレーションに対応している。とくに H.264/AVC フォーマットへのエンコードは、その規格の複雑度の高さから時間のかかる処理とされており、これがハードウェア・アクセラレーションにより極めて高速に実行できるのは大きな魅力である。
とはいうものの、その対応アプリケーション開発において難しいのは、GPU によるメディア・アクセラレーションの実行状況を適切に把握できるツールがないため、一体どの程度のパフォーマンスをもってよしとすればよいのかの基準がない、言い換えれば、GPU 側の動作状況が見えにくいため、ハードウェアの性能を十分に引き出しているのかどうかが非常につかみにくい点である。もちろん例えばビデオエンコードのパフォーマンスは入出力フレームサイズをはじめとする入力パラメーターによって大きく異なるし、またアプリケーションの具体的処理内容にも大きく依存する。
そのため、ハードウェア・アクセラレーションとはいっても、アプリケーションを離れて絶対的なパフォーマンス指標を持つことは難しい。ただ、そうだとしても、開発中のアプリケーションがハードウェア・アクセラレーション機能を十分に利用できているかどうかを視覚的に確認可能なツールがあれば、対応アプリケーションを開発していく上で、大きな助けになるだろう。
このようなニーズから、インテル® グラフィックス・パフォーマンス・アナライザー(インテル® GPA)が、近時の Version 4.1 へのバージョンアップで、メディア・アクセラレーションのプロファイリング機能を搭載した。インテル® GPA は、本来は、ゲーム・アプリケーションのパフォーマンスをプラットフォーム・レベルで解析するツールであったが、今回、Sandy Bridge の内蔵 GPU にメディア・アクセラレーション機能が搭載されたことに伴い、新機能として、メディア・パフォーマンスの解析ツールが追加されたのである。
本稿では、新しいメディア・パフォーマンス解析ツールに焦点をあてて、YUV ファイルの H.264/AVC フォーマットのエンコードを例にとり、インテル® GPA 4.1 の利用の仕方およびハードウェア・アクセラレーションを利用した際のパフォーマンスの引き出し方を考察してみよう。
なお、最新のインテル® GPA は、インテル® ソフトウェア・ネットワークにある「Intel GPA – Graphics Performance Analyzers」ページ (英語) よりダウンロードすることができます。
インテル® GPA メディア・パフォーマンス・アナライザー
インテル® GPA 4.1 をインストールしたら、インテル® GPA Monitor v4.1 を立ち上げ、タスクバー上の Intel GPA Monitor アイコンを右クリックして、[Media Performance] を選択する(図1)。すると、インテル® GPA 4.1 の [Media Performance] ウィンドウが立ち上がる(図2)。ここではリアルタイムに GPU 上のメディア・アクセラレーション機能の利用状況が確認可能だ。確認できるのは、”GPU General”(GPU 全般)、”GPU Execution Unit Engine” (GPU 実行エンジン)、”GPU Multi-Format Codec Engine(MFX)”(MFX エンジン)の3つである。
図 1 Media Performance Analyzer
ここで、GPU 全般は内蔵 GPU 全般の利用率、GPU 実行エンジンは GPU 上の汎用コアの利用率を表し、下段のテーブルには、実行中のアクセラレーション・モジュール名および利用率が表示される(ENCODE/DECODEなど)。また、MFX エンジンはメディア処理に特化した GPU 上のハードウェア・コンポーネントの総称を表し、テーブルについては GPU 実行エンジンと同様である。なお、ハードウェア・アクセラレーションによるメディア処理は、GPU 実行エンジンと MFX エンジンがドライバーにより協調的に利用されて実行されるため、例えば MFX エンジンだけがリアルタイム・モニター上で 100% になるわけではないことに留意されたい。
図 2 インテル® GPA 4.1 の [Media Performance] ウィンドウ
インテル® Media SDK 2.0 におけるエンコード API
それでは、ここでシンプルなエンコード・サンプル・アプリケーションを利用してリアルタイムにハードウェアの利用状況を確認してみよう。まずはエンコード処理における MSDK の鍵となる2つの API を確認しておこう(なお、詳細については MSDK 2.0 のパッケージに添付されているユーザーズ・マニュアルおよびサンプルソースをご参照願いたい)。
MFXVideoENCODE_EncodeFrameAsync(mfxSession session, mfxEncodeCtrl *ctrl, mfxFrameSurface1 *surface, mfxBitstream *bs, mfxSyncPoint *syncp);
MFXVideoCORE_SyncOperation(mfxSession session, mfxSyncPoint syncp, mfxU32 wait);
EncodeFrameAsync API は、入力フレーム、出力ストリーム格納先、および mfxSyncPoint を主要な引数として取り、エンコードの中核をなす API である。SyncOperation API は引数で指定した mfxSyncPoint に対応するエンコードのステータスをチェックし、完了していれば、EncodeFrameAsync API で指定された出力ストリーム格納先に、ビットストリームを出力する。
フレーム同期実行と非同期実行によるエンコード・パフォーマンスの違い
本稿では、MSDK 2.0 に添付されているエンコーダー・サンプルをさらに簡略化した、2つの異なる構成のサンプル・アプリケーションを用意し、それらを比較しつつ解析することにより、ハードウェア・アクセラレーションの具体的な動きを観察することにしよう。最初の構成は、
(1) 入力フレームをファイルから読み込み
(2) EncodeFrameAsync API を実行し
(3) その後 SyncOperation API でビットストリームを取得し
(4) それをファイルに書き出す
という動作を、フレーム単位で同期して行う構成で、これを便宜上「構成 1」とする。もう一方は、
(1) フレームプールを利用して、入力フレームを3枚分プールし
(2) プールされているフレーム分の EncodeFrameAsync API を非同期に実行し
(3) その後に、順次 SyncOperation API を実行し、ビットストリームを取得し
(4) ファイルに書き出す
もちろん、例えば複数の入力フレームが必要とされる場合など、常に厳密に上記のように動作するわけではないが、そのあたりは API が返すステータスにより対応してあるものとする。なお、いずれも主要な mfx parameter は以下のようにした。
TargetUsage は MFX_TARGETUSAGE_BALANCED モードに設定し、実行の際には、HD サイズ(1920×1080)の YUV フレームを、8Mbps CBR の設定で、300 フレーム分を H.264/AVC フォーマットにエンコードした。
// set mfx parameters mfxEncParams.mfx.CodecId = MFX_CODEC_AVC; mfxEncParams.IOPattern = MFX_IOPATTERN_IN_SYSTEM_MEMORY; mfxEncParams.mfx.FrameInfo.ChromaFormat = MFX_CHROMAFORMAT_YUV420; mfxEncParams.mfx.FrameInfo.FourCC = MFX_FOURCC_NV12; mfxEncParams.mfx.FrameInfo.PicStruct = MFX_PICSTRUCT_PROGRESSIVE; mfxEncParams.mfx.TargetUsage = MFX_TARGETUSAGE_BALANCED; mfxEncParams.mfx.RateControlMethod = MFX_RATECONTROL_CBR; mfxEncParams.mfx.NumThread = 0; mfxEncParams.mfx.EncodedOrder = 0; mfxOption.CAVLC = MFX_CODINGOPTION_OFF; // CAVAC
これらのサンプル・アプリケーションの実行中の様子をインテル® GPA メディア・パフォーマンス・アナライザーで観察し、ピーク値をキャプチャーしたのが図3と図4である。
図 3 構成 1 のアプリケーションの実行中の様子
図 4 構成 2 のアプリケーションの実行中の様子
計測結果を見てみると、ピークの数字で、構成 1 で GPU 全般が 62%、GPU 実行エンジンが 51%、MFX エンジンが 10% であるのに対し、構成 2 では、GPU 全般が 98%、GPU 実行エンジンが 83%、MFXが 25% となった。測定結果を見る限り、構成 2 の方がハードウェア・アクセラレーションの利用率が高く、パフォーマンスが高そうである。実際、アプリケーション側で 300 フレーム分のエンコード速度を計測してみると、設定 1 は 41 FPS 前後であるのに対し、設定 2 は 108 FPS に到達しており、倍以上パフォーマンスが違う。
GPU全般 | GPU実行エンジン | MFXエンジン | FPS | |
---|---|---|---|---|
構成 1(同期実行) | 62% | 51% | 10% | 約 41 FPS |
構成 2(非同期プール実行) | 98% | 83% | 25% | 約 108 FPS |
もっとも、構成 1 は、フレーム単位で同期してしまっているため、ファイル入出力によるウエイトが生じているのは明らかで、構成 2 のフレームプールを利用した非同期実行に比べてパフォーマンスが落ちるのは最初からある程度想像ができるだろう。
それでは、ハードウェア・アクセラレーションを最大限活用するには、ファイル入出力を非同期に実行すればそれでいいのだろうか?ここでは構成 1 のアプリケーションの実行の様子を、インテル® GPA プラットフォーム・アナライザーで解析することにより、インテル® クイック・シンク・ビデオのハードウェア・アクセラレーションによるパフォーマンスを最大限生かすための要件を具体的に明らかにしてみよう。
なお、筆者個人的には、構成 1 のような同期的なアプリケーションを用意して解析することをお勧めする。まず同期的な利用形態で、ハードウェア・アクセラレーションが、具体的に何がどのような順番で、どのように動作するのかを把握できなければ、非同期設定の解析は非常に困難であろう。本稿が同期実行の構成 1 に主眼を置いているのはそのためで、これを理解できれば、非同期設定やさまざまな状況に応用していくことは容易であろう。
なお、実際のところ本サンプルでは、わざわざ API の呼び出し方法を変えてあるわけではなく、フレーム・プールサイズを 1 に設定して同期実行にしているだけで、それ以外は全く同一のソース・コードを利用している。
次稿では、インテル® GPA プラットフォーム・アナライザーで、その内容を具体的に解析してみることにしよう。
著者紹介
岩本 成文 氏Software Engineer, Software and Services Group, Intel Corporation