Ускорение корреляции с графическими процессорами

В этом примере показано, как использовать графический процессор для ускорения перекрестной корреляции. Многие проблемы корреляции включают большие наборы данных и могут быть решены намного быстрее с помощью графический процессор. Этот пример требует лицензии пользователя Parallel Computing Toolbox™. Обратитесь к разделу Поддержка GPU по версии (Parallel Computing Toolbox), чтобы узнать, какие графические процессоры поддерживаются.

Введение

Начните, узнав некоторые основные сведения о графическом процессоре в вашей машине. Для доступа к графическому процессору используйте Parallel Computing Toolbox.

fprintf('Benchmarking GPU-accelerated Cross-Correlation.\n');

if ~(parallel.gpu.GPUDevice.isAvailable)
    fprintf(['\n\t**GPU not available. Stopping.**\n']);
    return;
else
    dev = gpuDevice;
    fprintf(...
    'GPU detected (%s, %d multiprocessors, Compute Capability %s)',...
    dev.Name, dev.MultiprocessorCount, dev.ComputeCapability);
end
Benchmarking GPU-accelerated Cross-Correlation.
GPU detected (TITAN Xp, 30 multiprocessors, Compute Capability 6.1)

Функции бенчмаркинга

Поскольку код, написанный для центрального процессора, может быть портирован для запуска на графическом процессоре, одна функция может использоваться для проверки как центрального процессора, так и графического процессора. Однако, поскольку код на графическом процессоре выполняется асинхронно от центрального процессора, при измерении эффективности следует соблюдать особые меры предосторожности. Прежде чем измерять время, необходимое для выполнения функции, убедитесь, что вся обработка графический процессор завершена, выполнив метод 'wait' на устройстве. Этот дополнительный вызов не влияет на эффективность центрального процессора.

Этот пример проверяет три различных типа перекрестной корреляции.

Простая перекрестная корреляция бенчмарка

В первом случае два вектора равного размера перекрестно коррелируются с использованием синтаксиса xcorr(u,v). Отношение времени выполнения центральный процессор к времени выполнения графический процессор построено относительно размера векторов.

fprintf('\n\n *** Benchmarking vector-vector cross-correlation*** \n\n');
fprintf('Benchmarking function :\n');
type('benchXcorrVec');
fprintf('\n\n');

sizes = [2000 1e4 1e5 5e5 1e6];
tc = zeros(1,numel(sizes));
tg = zeros(1,numel(sizes));
numruns = 10;

for s=1:numel(sizes);
    fprintf('Running xcorr of %d elements...\n', sizes(s));
    delchar = repmat('\b', 1,numruns);

    a = rand(sizes(s),1);
    b = rand(sizes(s),1);
    tc(s) = benchXcorrVec(a, b, numruns);
    fprintf([delchar '\t\tCPU  time : %.2f ms\n'], 1000*tc(s));
    tg(s) = benchXcorrVec(gpuArray(a), gpuArray(b), numruns);
    fprintf([delchar '\t\tGPU time :  %.2f ms\n'], 1000*tg(s));
end

%Plot the results
fig = figure;
ax = axes('parent', fig);
semilogx(ax, sizes, tc./tg, 'r*-');
ylabel(ax, 'Speedup');
xlabel(ax, 'Vector size');
title(ax, 'GPU Acceleration of XCORR');
drawnow;

 *** Benchmarking vector-vector cross-correlation*** 

Benchmarking function :

function t = benchXcorrVec(u,v, numruns)
%Used to benchmark xcorr with vector inputs on the CPU and GPU.
    
%   Copyright 2012 The MathWorks, Inc.

    timevec = zeros(1,numruns);
    gdev = gpuDevice;
    for ii=1:numruns
        ts = tic;
        o = xcorr(u,v); %#ok<NASGU>
        wait(gdev)
        timevec(ii) = toc(ts);
        fprintf('.');
    end
    t = min(timevec);
end


Running xcorr of 2000 elements...
		CPU  time : 0.21 ms
		GPU time :  4.26 ms
Running xcorr of 10000 elements...
		CPU  time : 1.03 ms
		GPU time :  4.37 ms
Running xcorr of 100000 elements...
		CPU  time : 14.04 ms
		GPU time :  6.28 ms
Running xcorr of 500000 elements...
		CPU  time : 55.98 ms
		GPU time :  16.09 ms
Running xcorr of 1000000 elements...
		CPU  time : 169.00 ms
		GPU time :  25.60 ms

Перекрестная корреляция столбца матрицы бенчмаркинга

Во втором случае столбцы матрицы A попарно перекрестно коррелируются, чтобы получить большой матричный выход всех корреляций, используя синтаксис xcorr (A). Отношение времени выполнения центральный процессор к времени выполнения графический процессор построено относительно размера матрицы А.

fprintf('\n\n *** Benchmarking matrix column cross-correlation*** \n\n');
fprintf('Benchmarking function :\n');
type('benchXcorrMatrix');
fprintf('\n\n');

sizes = floor(linspace(0,100, 11));
sizes(1) = [];
tc = zeros(1,numel(sizes));
tg = zeros(1,numel(sizes));
numruns = 10;

for s=1:numel(sizes);
    fprintf('Running xcorr (matrix) of a %d x %d matrix...\n', sizes(s), sizes(s));
    delchar = repmat('\b', 1,numruns);

    a = rand(sizes(s));
    tc(s) = benchXcorrMatrix(a, numruns);
    fprintf([delchar '\t\tCPU  time : %.2f ms\n'], 1000*tc(s));
    tg(s) = benchXcorrMatrix(gpuArray(a), numruns);
    fprintf([delchar '\t\tGPU time :  %.2f ms\n'], 1000*tg(s));
end

%Plot the results
fig = figure;
ax = axes('parent', fig);
plot(ax, sizes.^2, tc./tg, 'r*-');
ylabel(ax, 'Speedup');
xlabel(ax, 'Matrix Elements');
title(ax, 'GPU Acceleration of XCORR (Matrix)');
drawnow;

 *** Benchmarking matrix column cross-correlation*** 

Benchmarking function :

function t = benchXcorrMatrix(A, numruns)
%Used to benchmark xcorr with Matrix input on CPU and GPU.
    
%   Copyright 2012 The MathWorks, Inc.

    timevec = zeros(1,numruns);
    gdev = gpuDevice;
    for ii=1:numruns,
        ts = tic;
        o = xcorr(A); %#ok<NASGU>
        wait(gdev)
        timevec(ii) = toc(ts);
        fprintf('.');
    end
    t = min(timevec);
end


Running xcorr (matrix) of a 10 x 10 matrix...
		CPU  time : 0.18 ms
		GPU time :  5.00 ms
Running xcorr (matrix) of a 20 x 20 matrix...
		CPU  time : 0.48 ms
		GPU time :  4.83 ms
Running xcorr (matrix) of a 30 x 30 matrix...
		CPU  time : 0.85 ms
		GPU time :  4.84 ms
Running xcorr (matrix) of a 40 x 40 matrix...
		CPU  time : 3.38 ms
		GPU time :  5.57 ms
Running xcorr (matrix) of a 50 x 50 matrix...
		CPU  time : 5.60 ms
		GPU time :  5.22 ms
Running xcorr (matrix) of a 60 x 60 matrix...
		CPU  time : 8.49 ms
		GPU time :  5.39 ms
Running xcorr (matrix) of a 70 x 70 matrix...
		CPU  time : 20.43 ms
		GPU time :  5.92 ms
Running xcorr (matrix) of a 80 x 80 matrix...
		CPU  time : 26.79 ms
		GPU time :  6.24 ms
Running xcorr (matrix) of a 90 x 90 matrix...
		CPU  time : 40.04 ms
		GPU time :  6.89 ms
Running xcorr (matrix) of a 100 x 100 matrix...
		CPU  time : 49.69 ms
		GPU time :  7.32 ms

Бенчмаркинг двумерной перекрестной корреляции

Для последнего случая две матрицы, X и Y, перекрестно коррелируются с использованием xcorr2 (X, Y). X фиксирован в размере, в то время как Y разрешено изменяться. Ускорение построено относительно размера второй матрицы.

fprintf('\n\n *** Benchmarking 2-D cross-correlation*** \n\n');
fprintf('Benchmarking function :\n');
type('benchXcorr2');
fprintf('\n\n');

sizes = [100, 200, 500, 1000, 1500, 2000];
tc = zeros(1,numel(sizes));
tg = zeros(1,numel(sizes));
numruns = 4;
a = rand(100);

for s=1:numel(sizes);
    fprintf('Running xcorr2 of a 100x100 matrix and %d x %d matrix...\n', sizes(s), sizes(s));
    delchar = repmat('\b', 1,numruns);

    b = rand(sizes(s));
    tc(s) = benchXcorr2(a, b, numruns);
    fprintf([delchar '\t\tCPU  time : %.2f ms\n'], 1000*tc(s));
    tg(s) = benchXcorr2(gpuArray(a), gpuArray(b), numruns);
    fprintf([delchar '\t\tGPU time :  %.2f ms\n'], 1000*tg(s));
end

%Plot the results
fig = figure;
ax =axes('parent', fig);
semilogx(ax, sizes.^2, tc./tg, 'r*-');
ylabel(ax, 'Speedup');
xlabel(ax, 'Matrix Elements');
title(ax, 'GPU Acceleration of XCORR2');
drawnow;

fprintf('\n\nBenchmarking completed.\n\n');

 *** Benchmarking 2-D cross-correlation*** 

Benchmarking function :

function t = benchXcorr2(X, Y, numruns)
%Used to benchmark xcorr2 on the CPU and GPU.

%   Copyright 2012 The MathWorks, Inc.
 
    timevec = zeros(1,numruns);
    gdev = gpuDevice;
    for ii=1:numruns,
        ts = tic;
        o = xcorr2(X,Y); %#ok<NASGU>
        wait(gdev)
        timevec(ii) = toc(ts);
        fprintf('.');
    end
    t = min(timevec);
end


Running xcorr2 of a 100x100 matrix and 100 x 100 matrix...
		CPU  time : 20.35 ms
		GPU time :  6.96 ms
Running xcorr2 of a 100x100 matrix and 200 x 200 matrix...
		CPU  time : 42.87 ms
		GPU time :  11.72 ms
Running xcorr2 of a 100x100 matrix and 500 x 500 matrix...
		CPU  time : 125.23 ms
		GPU time :  39.67 ms
Running xcorr2 of a 100x100 matrix and 1000 x 1000 matrix...
		CPU  time : 386.59 ms
		GPU time :  88.46 ms
Running xcorr2 of a 100x100 matrix and 1500 x 1500 matrix...
		CPU  time : 788.38 ms
		GPU time :  165.04 ms
Running xcorr2 of a 100x100 matrix and 2000 x 2000 matrix...
		CPU  time : 1523.05 ms
		GPU time :  279.55 ms


Benchmarking completed.

Другие функции ускоренной обработки сигналов графический процессор

Существует несколько других функций обработки сигналов, которые могут выполняться на графическом процессоре. Эти функции включают fft, ifft, conv, фильтр, fftfilt и многое другое. В некоторых случаях можно добиться большого ускорения относительно центрального процессора. Полный список функций ускоренной обработки сигналов GPU см. в разделе «Ускорение алгоритма графического процессора» в документации по Signal Processing Toolbox™.

См. также

| (Parallel Computing Toolbox) | (Parallel Computing Toolbox)