Main Content

生成コードの GPU 実行プロファイリング

この例では、関数 gpucoder.profile を使用して、生成された CUDA® コードの実行プロファイリング レポートを生成する方法を示します。

GPU Coder プロファイラーは、生成されたコード内のタスクとカーネルの実行時間メトリクスを生成するソフトウェアインザループ (SIL) の実行を行います。この例では、GPU Coder の "霧の修正" の例で使用するための実行プロファイリング レポートを生成します。詳細については、霧の修正を参照してください。

サードパーティの必要条件

  • CUDA 対応 NVIDIA® GPU。

  • NVIDIA CUDA Toolkit およびドライバー。

  • NVIDIA Nsight™ システム。サポートされているコンパイラおよびライブラリのバージョンの詳細は、サードパーティ ハードウェアを参照してください。

  • コンパイラおよびライブラリの環境変数。環境変数の設定は、前提条件となる製品の設定を参照してください。

  • この例のプロファイリング ワークフローは、GPU パフォーマンス カウンターにアクセスする NVIDIA のプロファイリング ツールに依存します。CUDA Toolkit v10.1 以降では、NVIDIA はパフォーマンス カウンターへのアクセスを管理者ユーザーのみに制限します。GPU パフォーマンス カウンターをすべてのユーザーが使用できるようにするには、Permission issue with Performance Counters (NVIDIA) に記載されている手順を参照してください。

GPU 環境の検証

この例を実行するのに必要なコンパイラおよびライブラリが正しく設定されていることを検証するために、関数coder.checkGpuInstallを使用します。

envCfg = coder.gpuEnvConfig('host');
envCfg.BasicCodegen = 1;
envCfg.Quiet = 1;
coder.checkGpuInstall(envCfg);

霧修正のアルゴリズム

霧のかかった入力イメージを改善するために、アルゴリズムでは霧の除去に続けてコントラストの強調を実行します。図は、これら両方の演算手順を示しています。

この例では、霧のかかった RGB イメージを入力として受け取ります。霧の除去を実行するために、アルゴリズムではイメージのダーク チャネルを推定し、ダーク チャネルに基づいて大気光マップを計算し、フィルターを使用して大気光マップを調整します。復元段階で、入力イメージから調整済みの大気光マップを差し引くことにより、霧が取り除かれたイメージを作成します。

次にコントラスト強調段階で、イメージ内の強度値の範囲を評価し、コントラスト ストレッチを使用して値の範囲を拡大し、特徴をより明確に際立たせます。

FogRectificationAlgorithm.png

type fog_rectification.m
function [out] = fog_rectification(input) %#codegen

%   Copyright 2017-2019 The MathWorks, Inc.

coder.gpu.kernelfun;

% restoreOut is used to store the output of restoration
restoreOut = zeros(size(input),'double');

% Changing the precision level of input image to double
input = double(input)./255;

%% Dark channel Estimation from input
darkChannel = min(input,[],3);

% diff_im is used as input and output variable for anisotropic diffusion
diff_im = 0.9*darkChannel;
num_iter = 3;

% 2D convolution mask for Anisotropic diffusion
hN = [0.0625 0.1250 0.0625; 0.1250 0.2500 0.1250; 0.0625 0.1250 0.0625];
hN = double(hN);

%% Refine dark channel using Anisotropic diffusion.
for t = 1:num_iter
    diff_im = conv2(diff_im,hN,'same');
end

%% Reduction with min
diff_im = min(darkChannel,diff_im);

diff_im = 0.6*diff_im ;

%% Parallel element-wise math to compute
%  Restoration with inverse Koschmieder's law
factor = 1.0./(1.0-(diff_im));
restoreOut(:,:,1) = (input(:,:,1)-diff_im).*factor;
restoreOut(:,:,2) = (input(:,:,2)-diff_im).*factor;
restoreOut(:,:,3) = (input(:,:,3)-diff_im).*factor;
restoreOut = uint8(255.*restoreOut);
restoreOut = uint8(restoreOut);

%%
% Stretching performs the histogram stretching of the image.
% im is the input color image and p is cdf limit.
% out is the contrast stretched image and cdf is the cumulative prob.
% density function and T is the stretching function.

p = 5;
% RGB to grayscale conversion
im_gray = im2gray(restoreOut);
[row,col] = size(im_gray);

% histogram calculation
[count,~] = imhist(im_gray);
prob = count'/(row*col);

% cumulative Sum calculation
cdf = cumsum(prob(:));

% finding less than particular probability
i1 = length(find(cdf <= (p/100)));
i2 = 255-length(find(cdf >= 1-(p/100)));

o1 = floor(255*.10);
o2 = floor(255*.90);

t1 = (o1/i1)*[0:i1];
t2 = (((o2-o1)/(i2-i1))*[i1+1:i2])-(((o2-o1)/(i2-i1))*i1)+o1;
t3 = (((255-o2)/(255-i2))*[i2+1:255])-(((255-o2)/(255-i2))*i2)+o2;

T = (floor([t1 t2 t3]));

restoreOut(restoreOut == 0) = 1;

u1 = (restoreOut(:,:,1));
u2 = (restoreOut(:,:,2));
u3 = (restoreOut(:,:,3));

% Replacing the value from look up table
out1 = T(u1);
out2 = T(u2);
out3 = T(u3);

out = zeros([size(out1),3], 'uint8');
out(:,:,1) = uint8(out1);
out(:,:,2) = uint8(out2);
out(:,:,3) = uint8(out3);
return

実行プロファイリング レポートの生成

実行プロファイリング レポートを生成するには、ダイナミック ライブラリ ('dll') ビルド タイプを指定して、コード構成オブジェクトを作成します。関数 gpucoder.profile は Embedded Coder™ 構成オブジェクトのみを受け入れるため、coder.EmbeddedCodeConfig 構成オブジェクトを作成するオプションを有効にします。

cfg = coder.gpuConfig('dll','ecoder',true);
cfg.GpuConfig.MallocMode = 'discrete';

既定のしきい値 0 秒で gpucoder.profile を実行します。生成コードに多数の CUDA API またはカーネルの呼び出しがある場合、各呼び出しが合計時間のほんの一部しか占めていない可能性は高くなります。そのような場合、意味のあるプロファイリング レポートを生成するには、低い (0 以外の) しきい値を設定します。実行数の値を非常に低い数値 (5 未満) に設定することは推奨されません。これでは一般的な実行プロファイルが正確に表現されないためです。

inputImage = imread('foggyInput.png');
inputs  = {inputImage};
designFileName = 'fog_rectification';

gpucoder.profile(designFileName, inputs, ...
    'CodegenConfig', cfg, 'Threshold', 0, 'NumCalls', 10);
Code generation successful: View report

### Starting SIL execution for 'fog_rectification'
    To terminate execution: clear fog_rectification_sil
    Execution profiling data is available for viewing. Open Simulation Data Inspector.
    Execution profiling report available after termination.
 
### Host application produced the following standard error (stderr) messages:
Warning: LBR backtrace method is not supported on this platform. DWARF backtrace method will be used.
Collecting data...

 
### Stopping SIL execution for 'fog_rectification'

関数 fog_rectification のコード実行プロファイリング レポート

コード実行プロファイリング レポートは、SIL 実行から収集されたデータに基づくメトリクスを提供します。実行時間の計算は、SIL または PIL テスト ハーネスに追加された計測プローブか、各コンポーネントについて生成されたコードの内部に追加された計測プローブで記録したデータを基に行われます。詳細については、View Execution Times (Embedded Coder)を参照してください。

これらの数値は代表的なものです。実際の値はハードウェア設定によって異なります。このプロファイリングは、6 コアの 3.5 GHz Intel® Xeon® CPU および NVIDIA TITAN XP GPU を搭載したマシンで MATLAB R2022b を使用して行われました。

まとめ

このセクションでは、レポートの作成に関する情報を提供します。

プロファイリングされたコードのセクション

このセクションには、プロファイリングされたコード セクションに関する情報が含まれています。レポートには、以下に対する時間測定値が含まれます。

  • 関数 entry_point_fn_initialize (例: fog_rectification_initialize)

  • エントリポイント関数 (例: fog_rectification)

  • 関数 entry_point_fn_terminate (例: fog_rectification_terminate)

  • [セクション] 列には、コードが生成される関数の名前がリストされます。

  • [最大実行時間] は、コード セクションが開始してから終了するまでの最長時間です。

  • [平均実行時間] は、コード セクションが開始してから終了するまでの平均時間です。

  • [最大自己時間] は、子セクションの時間を除いた最大実行時間です。

  • [平均自己時間] は、子セクションの時間を除いた平均実行時間です。

  • [呼び出し] は、コード セクションに対する呼び出しの数を示します。

  • コマンド ウィンドウでコード セクションの実行時間メトリクスを表示するには、対応する行でアイコン icon_view_code_sect_obj.png をクリックします。

  • 測定された実行時間を表示するには、シミュレーション データ インスペクターのアイコン icon_simulation_data_inspectora5cc10a7e5374a15280c4ca6011f26f9.png をクリックします。シミュレーション データ インスペクターを使用して、さまざまな実行からのプロットを管理および比較できます。

  • 実行時間の分布を表示するには、アイコン code_exec_profiling_report_icon_frequency_distribution.png をクリックします。

既定では、レポートはミリ秒 (10-3 秒) 単位の時間を表示します。時間単位と数値表示形式は指定できます。たとえば、時間をマイクロ秒 (10-6 秒) で表示するには、次のようにreport (Embedded Coder)コマンドを使用します。

executionProfile=getCoderExecutionProfile('fog_rectification');
report(executionProfile, ...
    'Units', 'Seconds', ...
    'ScaleFactor', '1e-06', ...
    'NumericFormat', '%0.3f')
ans = 
'/local-ssd/lnarasim/MATLAB/ExampleManager/lnarasim.Bdoc22b.j1984243/gpucoder-ex87489778/codegen/dll/fog_rectification/html/orphaned/ExecutionProfiling_f31bfb52dfefde93.html'

レポートには、タイマーがキャリブレーションされている場合、つまり 1 秒あたりのタイマー刻みの数値がわかっている場合にのみ、時間が秒単位で表示されます。Windows® マシンでは、SIL シミュレーション用にソフトウェアによってこの値が決定されます。Linux® マシンでは、タイマーを手動でキャリブレーションしなければなりません。たとえば、プロセッサ速度が 3.5 GHz の場合、1 秒あたりのタイマー刻みの数値を次のように指定します。

executionProfile.TimerTicksPerSecond = 3.5e9;

パーセント単位の実行時間

このセクションでは、関数の実行時間を、呼び出し元関数の実行時間と合計実行時間のパーセンテージとして提供します。これは、生成コードにおけるパフォーマンス ボトルネックを特定するのに役立ちます。

fog_rectification の GPU プロファイリング トレース

セクション 4 には、実行時間がしきい値を上回る GPU 呼び出しの完全なトレースが表示されます。プロファイリング トレースのスニペットが表示されます。

fog_rectification の GPU プロファイリングの概要

レポートのセクション 5 には、セクション 4 に表示されている GPU 呼び出しの概要が示されます。cudaFree は、fog_rectification の 1 回の実行あたり 15 回呼び出されており、9 回の fog_rectification の実行に対する 15 回の cudaFree 呼び出しにかかった平均時間は 1.3790 ミリ秒です。この概要は、かかった時間の降順で並べ替えられており、最も時間がかかった GPU 呼び出しをユーザーが把握しやすくなっています。

定義

このセクションでは、いくつかのメトリクスについて説明します。