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