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