В этом примере показано, как arrayfun
может использоваться, чтобы запустить функцию MATLAB® исходно на графическом процессоре. Когда функция MATLAB содержит много поэлементных операций, arrayfun
может обеспечить улучшенную производительность когда по сравнению с простым выполнением функции MATLAB непосредственно на графическом процессоре с gpuArray входными данными. Функция MATLAB может быть в ее собственном файле или может быть вложенной или анонимной функцией. Это должно содержать только скалярные операции и арифметику.
Мы помещаем пример в функцию, чтобы позволить вложенные функции:
function paralleldemo_gpu_arrayfun
Правило Горнера позволяет эффективную оценку расширений степенного ряда. Мы будем использовать его, чтобы вычислить первые 10 терминов расширения степенного ряда для показательной функции exp
. Мы можем реализовать это как функцию 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
для графического процессораЧтобы запустить эту функцию на графическом процессоре с минимальными изменениями кода, мы могли передать gpuArray
возразите, как введено против horner
функция. Начиная с horner
содержит только отдельные поэлементные операции, мы не можем понять очень хорошую эффективность на графическом процессоре при выполнении каждой операции по одному. Однако мы можем улучшать производительность путем выполнения всех поэлементных операций в horner
функционируйте одновременно использование arrayfun
.
Запускать эту функцию на графическом процессоре с помощью arrayfun
, мы используем указатель на horner
функция. horner
автоматически адаптируется к различному размеру и входным параметрам типа. Мы можем сравнить результаты, вычисленные на графическом процессоре с помощью обоих gpuArray
объекты и arrayfun
со стандартным выполнением центрального процессора MATLAB просто путем выполнения функции непосредственно.
hornerFcn = @horner;
Мы создаем некоторые входные параметры различных типов и размеров, и используем gpuArray
отправить их в графический процессор.
data1 = rand( 2000, 'single' ); data2 = rand( 1000, 'double' ); gdata1 = gpuArray( data1 ); gdata2 = gpuArray( data2 );
horner
на графическом процессореОценивать horner
функция на графическом процессоре, у нас есть два варианта. С минимальными изменениями кода мы можем выполнить исходную функцию на графическом процессоре путем обеспечения gpuArray
возразите, как введено. Однако, чтобы улучшать производительность на графическом процессоре вызывают arrayfun
, использование того же соглашения о вызовах как исходная функция MATLAB.
Мы можем сравнить точность результатов путем выполнения исходной функции непосредственно в MATLAB на центральном процессоре. Мы ожидаем некоторые небольшие числовые различия, потому что арифметика с плавающей точкой на графическом процессоре точно не совпадает с арифметикой, выполняемой на центральном процессоре.
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
Мы можем сравнить эффективность версий графического процессора к нативной версии ЦП MATLAB. Графические процессоры текущего поколения имеют намного лучшую эффективность в одинарной точности, таким образом, мы сравниваем это.
% 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