Main Content

このページの翻訳は最新ではありません。ここをクリックして、英語の最新版を参照してください。

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

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

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

functionparalleldemo_gpu_arrayfun

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

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

functiony = horner(x)%HORNER - series expansion for exp(x) using Horner's ruley = 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 executiontic hornerFcn( data1 ); tcpu = toc;% GPU execution using only gpuArray objectstgpuObject = gputimeit(@() hornerFcn(gdata1));% GPU execution using gpuArray objects with arrayfuntgpuArrayfun = 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