パフォーマンスの見積もり

パフォーマンスを計測するためのコードのプロファイリングおよび計測用関数呼び出しの追加

コードのプロファイリングおよびインストルメント化の最初の主なタスクは、ハードウェアにインプリメントするのに適したアプリケーション コードの部分を特定して、ハードウェアで実行した場合に全体的なパフォーマンスが大幅に向上するようにすることです。コードの計算負荷の高い部分はハードウェア アクセラレーションに適しており、ハードウェアと CPU およびメモリ間でデータをストリーミングして計算と通信をオーバーラップさせることができる場合に特に適しています。ソフトウェア プロファイリングは、プログラムの CPU の負荷が高い部分を特定する標準的な方法です。アクセラレーションには向いていないのは、たとえば計算よりもアクセラレータのデータ転送に時間がかかる関数です。SDSoC™ 環境には、gprof、非介入 TCF (Target Communication Framework) プロファイラー、Eclipse のパフォーマンス解析パースペクティブなどのザイリンクス SDK ツールに含まれるパフォーマンスおよびプロファイリング機能がすべて含まれています。

スタンドアロン アプリケーションに対して TCF プロファイラーを実行するには、次の手順に従います。

  1. [Project Explorer] ビューでプロジェクトを右クリックし、[Build Configurations] > [Set Active] > [Debug] をクリックして、アクティブなビルド コンフィギュレーションを [Debug] に設定します。
  2. [Project Explorer] ビューでプロジェクト名を右クリックし、[Debug As] > [Launch on hardware (SDx Application Debugger] をクリックしてデバッガーを起動します。
    注記: ボードをコンピューターに接続して電源をオンにしておく必要があります。アプリケーションが main() に入る地点でブレークします。
  3. [Window] > [Show View] > [Other] をクリックして TCF プロファイラーを起動します。表示されたウィンドウで [Debug] を展開し、[TCF profiler] を選択します。
  4. [TCF Profiler] タブの上部にある緑色の [Start] ボタンをクリックして TCF プロファイラーを開始します。
  5. [Profiler Configuration] ダイアログ ボックスで [Aggregate per function] をイネーブルにします。
  6. プロファイリングを開始するには、[Resume] ボタンをクリックするか F8 キーを押します。プログラムが実行を完了し、exit() 関数でブレークします。
  7. [TCF Profiler] タブで結果を確認します。

プロファイリングは、CPU プログラム カウンターのサンプリングおよび実行中のプログラムへの相関に基づいてコードのよく使用される領域を検索するための統計的な手法です。プログラムのパフォーマンスを計測するもう 1 つの方法として、実行中のプログラムの異なる部分に実際にかかる時間を判断するため、アプリケーションに計測用の関数呼び出しを追加する方法があります。

[TCF Profiler] タブには、Standalone または Linux OS アプリケーションのいずれかに関連する詳細な情報が含まれます。前の手順に示すように、プロファイラーを使用するために追加のコンパイル オプションは必要ありません。

注記: このタイプのハードウェアのプロファイルには、JTAG 接続が必要です。

SDSoC 環境の sds_lib ライブラリには、次の例に示すように、アプリケーション パフォーマンスの計測に使用可能な単純なソース コード アノテーション ベースの、タイム スタンプ API が含まれます。

/*
 * @return value of free-running 64-bit Zynq(TM) global counter
 */
unsigned long long sds_clock_counter(void);

この API を使用してタイムスタンプを収集してそれらの差を調べることにより、プログラムの主要な部分の時間を判断できます。たとえば、次のコード例に示すように、データ転送やハードウェア関数の全体的な実行時間を計測できます。

class perf_counter
{
public:
     uint64_t tot, cnt, calls;
     perf_counter() : tot(0), cnt(0), calls(0) {};
     inline void reset() { tot = cnt = calls = 0; }
     inline void start() { cnt = sds_clock_counter(); calls++; };
     inline void stop() { tot += (sds_clock_counter() - cnt); };
     inline uint64_t avg_cpu_cycles() { return (tot / calls); };
};

extern void f();
void measure_f_runtime()
{
     perf_counter f_ctr;
     f_ctr.start();
     f()
     f_ctr.stop();
     std::cout << "Cpu cycles f(): " << f_ctr.avg_cpu_cycles()
     	       << std::endl;
}

SDSoC 環境内のパフォーマンス見積もり機能はこの API を使用し、ハードウェア インプリメンテーションに選択された関数をインストルメント化し、ターゲット上でアプリケーションを実行して実際の実行時間を計測して、ハードウェア関数の見積もりの実行時間と比較します。

注記: アプリケーションの分割には CPU の負荷が高い関数をプログラマブル ロジックに移行するのが経験的に最も信頼性の高い方法ですが、システム パフォーマンスが向上するとはかぎらないので、アルゴリズムを変更してメモリ アクセスを最適化することが必要な場合があります。CPU の外部メモリへのランダム アクセス速度は、マルチレベル キャッシュおよび高速クロック (通常プログラマブル ロジックよりも 2 ~ 8 倍高速) により、プログラマブル ロジックで達成できる速度よりもかなり速くなります。大型のインデックス セットのインデックスを並べ替えるソート ルーチンなどの広いアドレス範囲に対するポインター変数の処理は CPU には適していますが、関数をプログラマブル ロジックに移動するとマイナスになることがあります。これはそのような計算関数がハードウェアに移動する良い候補ではないということではなく、コードまたはアルゴリズムを再構成することが必要な場合があるということです。これは、DSP および GPU コプロセッサの既知の問題です。

SDSCC/SDS++ パフォーマンス見積もりフロー オプション

完全なビットストリームのコンパイルには、ソフトウェアのコンパイルよりもかなり時間がかかります。そのため、sds++/sdscc (sds++ と呼ぶ) には、ハードウェア関数呼び出しの実行時間の改善を見積もるパフォーマンス見積もりオプションが含まれています。

[Application Project Settings] で [Estimate Performance] チェック ボックスをオンにすると、現在のビルド コンフィギュレーションでパフォーマンス見積もりがイネーブルになり、プロジェクトがビルドされます。

図: [Application Project Settings] でのパフォーマンス見積もりの設定

スピードアップの見積もりは、2 段階のプロセスです。

  1. SDSoC 環境でハードウェア関数をコンパイルしてシステムを生成します。システムをビットストリームに合成する代わりに、sds++ でハードウェア関数のレイテンシ見積もりとハードウェア関数呼び出し元のデータ転送見積もり時間に基づいて、パフォーマンスが見積もられます。
  2. パフォーマンス ベースラインおよびパフォーマンス見積もりを確認するには、生成されたパフォーマンス レポートで [Click Here] をクリックしてインストルメント化されたバージョンのソフトウェアをターゲットで実行します。

パフォーマンス レポートの使用方法に関するチュートリアルは、『SDSoC 環境チュートリアル: 概要』 (UG1028) を参照してください。

コマンド ラインからパフォーマンス見積もりを生成することもできます。ソフトウェア ランタイムに関するデータを収集するため、まず -perf-funcs オプションを使用してプロファイルする関数を指定し、-perf-root オプションを使用してプロファイルされる関数への呼び出しを含むルート関数を指定します。

これにより、sds++ システム コンパイラでこれらの関数がインストルメント化され、ボードでアプリケーションを実行したときに自動的にランタイム データが収集されます。インストルメント化されたアプリケーションをターゲットで実行すると、プログラムにより SD カードに swdata.xml という実行のランタイム パフォーマンス データを含むファイルが作成されます。

swdata.xml をホストにコピーし、ハードウェア関数呼び出しごとおよび –perf-root で指定した最上位関数でのパフォーマンス向上を見積もるビルドを実行します。–perf-est オプションを使用して、swdata.xml をこのビルドの入力データとして指定します。

次の表に、アプリケーションをビルドするのに通常使用される sds++ システム コンパイラ オプションを示します。

表 1. よく使用される sds++ オプション
オプション 説明
-perf-funcs function_name_list インストルメント化されたソフトウェア アプリケーションでプロファイリングするすべての関数をカンマで区切って指定します。
-perf-root function_name プロファイリングする関数へのすべての呼び出しを含むルート関数を指定します。デフォルトは main 関数です。
-perf-est data_file インストルメント化されたソフトウェア アプリケーションをターゲット上で実行したときに生成されたランタイム データを含むファイルを指定します。ハードウェア アクセラレーションされた関数のパフォーマンス向上を見積もります。このファイルのデフォルト名は、swdata.xml です。
-perf-est-hw-only ソフトウェア実行データを収集せずに見積もりフローを実行します。このオプションを使用すると、ベースラインとの比較は含まれませんが、ハードウェア レイテンシおよびリソース使用率を確認できます。
注意:
プロファイル データを収集するためにボード上の sd_card イメージを実行したら、cd /; sync; umount /mnt; と入力します。これにより、swdata.xml ファイルが SD カードに書き込まれます。