exponenta event banner

Повышение производительности отдельных функций MATLAB ® на GPU с помощью ARRAYFUN

В этом примере показано, как arrayfun может использоваться для выполнения функции MATLAB ® на графическом процессоре. Если функция MATLAB содержит множество операций по элементам ,arrayfun может обеспечить улучшенную производительность по сравнению с простым выполнением функции MATLAB непосредственно на GPU с входными данными 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 для графического процессора

Чтобы запустить эту функцию на GPU с минимальными изменениями кода, мы можем передать gpuArray объект в качестве входных данных для horner функция. С тех пор horner содержит только отдельные операции по элементам, мы можем не реализовать очень хорошую производительность графического процессора при выполнении каждой операции по одному. Однако мы можем улучшить производительность, выполнив все операции по элементам в horner функция за один раз с использованием arrayfun.

Для запуска этой функции на графическом процессоре с помощью arrayfun, мы используем ручку для horner функция. horner автоматически адаптируется к различным входам размера и типа. Мы можем сравнить результаты, вычисленные на GPU, используя оба gpuArray объекты и arrayfun при стандартном выполнении MATLAB CPU просто путем непосредственной оценки функции.

hornerFcn = @horner;

Создание входных данных

Мы создаем некоторые входные данные различных типов и размеров и используем gpuArray отправить их в ГПУ.

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

Оценить horner на GPU

Чтобы оценить horner функция на GPU, у нас есть два варианта. С минимальными изменениями кода мы можем оценить исходную функцию на GPU, предоставив gpuArray объект в качестве входных данных. Однако для повышения производительности при вызове GPU arrayfun, используя то же соглашение о вызове, что и исходная функция MATLAB.

Мы можем сравнить точность результатов, оценив исходную функцию непосредственно в MATLAB на CPU. Мы ожидаем некоторые небольшие числовые различия, поскольку арифметика с плавающей запятой на 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

Сравнение производительности графического процессора и ЦП

Мы можем сравнить производительность версий графического процессора с собственной версией процессора 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