ドキュメンテーション

最新のリリースでは、このページがまだ翻訳されていません。 このページの最新版は英語でご覧になれます。

arrayfun を使用した、要素単位の MATLAB® 関数の GPU におけるパフォーマンス改善

この例では、arrayfun を使用して MATLAB® 関数を GPU でネイティブに実行する方法を説明します。MATLAB 関数に要素単位の演算が多数含まれている場合、arrayfun を使用すると、gpuArray 入力データを用いて MATLAB 関数を GPU で直接実行する場合に比べパフォーマンスを改善できます。MATLAB 関数は独自のファイルに入れるか、あるいは入れ子関数や無名関数とすることができます。関数に含まれるのはスカラー演算と算術演算に限られます。

例を関数に配置して、入れ子関数を可能にします。

function paralleldemo_gpu_arrayfun

Horner 法を使用した指数の計算

Horner 法では、べき級数展開を効率的に評価できます。これを使用して、指数関数 exp のべき級数展開の最初の 10 項を計算します。これは MATLAB 関数として実装できます。

function y = horner(x)
%HORNER - series expansion for exp(x) using Horner's rule
y = 1 + x.*(1 + x.*((1 + x.*((1 + ...
        x.*((1 + x.*((1 + x.*((1 + x.*((1 + ...
        x.*((1 + x./9)./8))./7))./6))./5))./4))./3))./2));
end

horner を GPU で用いるための準備

最小限のコード変更でこの関数を GPU で実行するために、gpuArray オブジェクトを入力として関数 horner に渡すことができます。horner には要素単位の演算しか含まれていないため、各演算を 1 つずつ実行すると、GPU でさほど優れたパフォーマンスは実現できない可能性があります。しかし、arrayfun を使用して関数 horner 内の要素単位の演算をすべて一度に実行することで、パフォーマンスを改善できます。

arrayfun を使用して GPU でこの関数を実行するには、関数 horner のハンドルを使用します。horner は、異なるサイズと型の入力に自動的に適応します。関数を直接評価するだけで、gpuArray オブジェクトと arrayfun の両方を使用して GPU で計算された結果を、標準 MATLAB の CPU での実行と比較できます。

hornerFcn = @horner;

入力データの作成

型とサイズの異なるいくつかの入力を作成し、gpuArray を使用して GPU に送信します。

data1  = rand( 2000, 'single' );
data2  = rand( 1000, 'double' );
gdata1 = gpuArray( data1 );
gdata2 = gpuArray( data2 );

GPU での horner の評価

GPU で関数 horner を評価するには、2 つの選択肢があります。gpuArray オブジェクトを入力として指定することにより、コード変更は最小限のまま元の関数を GPU で評価できます。しかし、GPU でのパフォーマンスを高めるには、元の MATLAB 関数と同じ呼び出し規則を使用して arrayfun を呼び出します。

結果の精度を比較するには、CPU を使った MATLAB で元の関数を直接評価します。GPU の浮動小数点演算は CPU で実行される演算と正確には一致しないため、数値はわずかに異なると予想されます。

gresult1 = arrayfun( hornerFcn, gdata1 );
gresult2 = arrayfun( hornerFcn, gdata2 );

comparesingle = max( max( abs( gresult1 - horner( data1 ) ) ) );
comparedouble = max( max( abs( gresult2 - horner( data2 ) ) ) );
fprintf( 'Maximum discrepancy for single precision: %g\n', comparesingle );
fprintf( 'Maximum discrepancy for double precision: %g\n', comparedouble );
Maximum discrepancy for single precision: 2.38419e-07
Maximum discrepancy for double precision: 0

GPU と CPU のパフォーマンスの比較

GPU バージョンのパフォーマンスを、ネイティブの MATLAB CPU バージョンと比較できます。現在の世代の GPU は単精度でのパフォーマンスにおいてずっと優れているため、これを比較します。

% CPU execution
tic
hornerFcn( data1 );
tcpu = toc;

% GPU execution using only gpuArray objects
tgpuObject = gputimeit(@() hornerFcn(gdata1));

% GPU execution using gpuArray objects with arrayfun
tgpuArrayfun = gputimeit(@() arrayfun(hornerFcn, gdata1));


fprintf( 'Speed-up achieved using gpuArray objects only: %g\n',...
    tcpu / tgpuObject );
fprintf( 'Speed-up achieved using gpuArray objects with arrayfun: %g\n',...
    tcpu / tgpuArrayfun );
Speed-up achieved using gpuArray objects only: 24.6764
Speed-up achieved using gpuArray objects with arrayfun: 98.3555
end