Ускорение обработки сигналов через генерацию кода

Примечание

Бенчмарки в этом примере были измерены на машине с четырьмя физическими ядрами.

Этот пример показывает, как ускорить алгоритм обработки сигналов в MATLAB® использование codegen (MATLAB Coder) и dspunfold функций. Можно сгенерировать исполняемый файл MATLAB (MEX-функция) из всей функции MATLAB или определенных частей функции MATLAB. Когда вы запускаете MEX-функцию вместо оригинального кода MATLAB, скорость симуляции может значительно увеличиться. Чтобы сгенерировать эквивалент MEX, алгоритм должен поддержать генерацию кода.

Использовать codegen (MATLAB Coder), необходимо установить MATLAB Coder™. Использовать dspunfoldнеобходимо установить MATLAB Coder и DSP System Toolbox™.

Использовать dspunfold в Windows и Linux необходимо использовать компилятор, поддерживающий интерфейс приложения Open Multi-Processing (OpenMP). См. «Поддерживаемые компиляторы».

Алгоритм конечной импульсной характеристики

Рассмотрим простой алгоритм конечной импульсной характеристики, чтобы ускориться. Скопируйте firfilter код функции в firfilter.m файл.

function [y,z1] = firfilter(b,x)
% Inputs:
%   b - 1xNTaps row vector of coefficients
%   x - A frame of  noisy input 

% States:
%   z, z1 - NTapsx1 column vector of states

% Output:
%   y - A frame of filtered output
 
persistent z;

if (isempty(z))
    z = zeros(length(b),1);
end
Lx = size(x,1);
y = zeros(size(x),'like',x);

z1 = z;
for m = 1:Lx
    % Load next input sample
    z1(1,:) = x(m,:);
    
    % Compute output
    y(m,:) = b*z1;
    
    % Update states
    z1(2:end,:) = z1(1:end-1,:);
    z = z1;
end

 firfilter функция принимает вектор коэффициентов фильтра , b, шумный входной сигнал, x, в качестве входов. Сгенерируйте коэффициенты фильтра, используя fir1 функция.

NTaps = 250;
Fp = 4e3/(44.1e3/2);
b = fir1(NTaps-1,Fp);

Фильтруйте поток сигнала шумной синусоиды при помощи firfilter функция. Синусоида имеет формат кадра 4000 выборок и частоту дискретизации 192 кГц. Сгенерируйте синусоиду, используя dsp.SineWave Системные object™. Шум является белым Гауссовым со средним значением 0 и отклонением 0,02. Назовите эту функцию firfilter_sim.  firfilter_sim функция вызывает firfilter функция на шумном входе.

function totVal = firfilter_sim(b)
% Create the signal source
Sig = dsp.SineWave('SamplesPerFrame',4000,'SampleRate',19200);
totVal = zeros(4000,500);
R  = 0.02;

clear firfilter;

% Iteration loop. Each iteration filters a frame of the noisy signal.
for i = 1 : 500
    trueVal = Sig();                        % Original sine wave 
    noisyVal = trueVal + sqrt(R)*randn;     % Noisy sine wave
    filteredVal = firfilter(b,noisyVal);    % Filtered sine wave
    totVal(:,i) = filteredVal;              % Store the entire sine wave
end

Управляемый firfilter_sim и измерьте скорость выполнения. Скорость выполнения изменяется в зависимости от машины.

tic;totVal = firfilter_sim(b);t1 = toc;
fprintf('Original Algorithm Simulation Time: %4.1f seconds\n',t1);
Original Algorithm Simulation Time:  7.8 seconds

Ускорение конечной импульсной характеристики с помощью codegen

Звонить codegen на firfilter, и сгенерировать его MEX эквивалент, firfilter_mex. Сгенерируйте и передайте коэффициенты фильтра и сигнал синусоиды как входы к firfilter функция.

Ntaps = 250;
Sig = dsp.SineWave('SamplesPerFrame',4000,'SampleRate',19200); % Create the Signal Source
R = 0.02;           
trueVal = Sig();                    % Original sine wave
noisyVal = trueVal + sqrt(R)*randn; % Noisy sine wave
Fp = 4e3/(44.1e3/2);
b = fir1(Ntaps-1,Fp);               % Filter coefficients

codegen firfilter -args {b,noisyVal}

В firfilter_sim функция, замена firfilter(b,noisyVal) вызов функции с firfilter_mex(b,noisyVal). Назовите эту функцию firfilter_codegen.

function totVal = firfilter_codegen(b)
% Create the signal source
Sig = dsp.SineWave('SamplesPerFrame',4000,'SampleRate',19200);
totVal = zeros(4000,500);
R  = 0.02;

clear firfilter_mex;

% Iteration loop. Each iteration filters a frame of the noisy signal.
for i = 1 : 500
    trueVal = Sig();                           % Original sine wave 
    noisyVal = trueVal + sqrt(R)*randn;        % Noisy sine wave
    filteredVal = firfilter_mex(b,noisyVal);   % Filtered sine wave
    totVal(:,i) = filteredVal;                 % Store the entire sine wave
end

Управляемый firfilter_codegen и измерьте скорость выполнения. Скорость выполнения изменяется в зависимости от машины.

tic;totValcodegen = firfilter_codegen(b);t2 = toc;
fprintf('Algorithm Simulation Time with codegen: %5f seconds\n',t2);
fprintf('Speedup factor with codegen: %5f\n',(t1/t2));
Algorithm Simulation Time with codegen: 0.923683 seconds
Speedup factor with codegen: 8.5531

Ускорение усиления приблизительно 8.5.

Ускорение конечной импульсной характеристики с помощью dspunfold

dspunfold функция генерирует многопоточный файл MEX, который может улучшить ускорение усиления еще больше.

dspunfold также генерирует однопоточный файл MEX и функцию самодиагностического анализатора. Многопоточный файл MEX использует многоядерную архитектуру процессора хоста-компьютера. Однопоточный файл MEX аналогичен файлу MEX, который codegen функция генерирует. Функция анализатора измеряет ускорение усиления многопоточного файла MEX по однопоточному файлу MEX.

Звонить dspunfold на firfilter и сгенерируйте его многопоточный эквивалент MEX, firfilter_mt. Определите длину состояния в выборках с помощью -f опция, которая может улучшить ускорение усиления дальше. -s auto инициирует автоматическое обнаружение длины состояния. Для получения дополнительной информации об использовании -f и -s опции, см. dspunfold.

dspunfold firfilter -args {b,noisyVal} -s auto -f [false,true]
State length: [autodetect] samples, Repetition: 1, Output latency: 8 frames, Threads: 4
Analyzing: firfilter.m
Creating single-threaded MEX file: firfilter_st.mexw64
Searching for minimal state length (this might take a while)
Checking stateless ... Insufficient
Checking 4000 samples ... Sufficient
Checking 2000 samples ... Sufficient
Checking 1000 samples ... Sufficient
Checking 500 samples ... Sufficient
Checking 250 samples ... Sufficient
Checking 125 samples ... Insufficient
Checking 187 samples ... Insufficient
Checking 218 samples ... Insufficient
Checking 234 samples ... Insufficient
Checking 242 samples ... Insufficient
Checking 246 samples ... Insufficient
Checking 248 samples ... Insufficient
Checking 249 samples ... Sufficient
Minimal state length is 249 samples
Creating multi-threaded MEX file: firfilter_mt.mexw64
Creating analyzer file: firfilter_analyzer.p

Инструмент автоматического обнаружения длины состояния обнаруживает точную длину состояния 259 выборки.

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

firfilter_analyzer([b;0.5*b;0.6*b],[noisyVal;0.5*noisyVal;0.6*noisyVal]);
Analyzing multi-threaded MEX file firfilter_mt.mexw64. For best results, 
please refrain from interacting with the computer and stop other processes until the 
analyzer is done.
Latency = 8 frames
Speedup = 3.2x

firfilter_mt имеет коэффициент ускоренного усиления 3.2 при сравнении с однопоточным файлом MEX, firfilter_st. Чтобы увеличить скорость дальнейшего, увеличьте коэффициент повторения с помощью -r опция. Компромисс заключается в том, что задержка на выходе увеличивается. Используйте коэффициент повторения 3. Задайте точную длину состояния, чтобы уменьшить накладные расходы и увеличить скорость еще больше.

dspunfold firfilter -args {b,noisyVal} -s 249 -f [false,true] -r 3
State length: 249 samples, Repetition: 3, Output latency: 24 frames, Threads: 4
Analyzing: firfilter.m
Creating single-threaded MEX file: firfilter_st.mexw64
Creating multi-threaded MEX file: firfilter_mt.mexw64
Creating analyzer file: firfilter_analyzer.p

Вызовите функцию анализатора.

firfilter_analyzer([b;0.5*b;0.6*b],[noisyVal;0.5*noisyVal;0.6*noisyVal]);
Analyzing multi-threaded MEX file firfilter_mt.mexw64. For best results, 
please refrain from interacting with the computer and stop other processes 
until the analyzer is done.
Latency = 24 frames
Speedup = 3.8x

Коэффициент ускорения усиления 3.8или примерно в 32 раза больше скорости выполнения исходной симуляции.

Для этого конкретного алгоритма можно увидеть, что dspunfold генерирует высоко оптимизированный код, без необходимости записывать какой-либо код C or C++. Ускорение усиления масштабируется с количеством ядер на вашей хост-машине.

Функция filter конечной импульсной характеристики в этом примере является только иллюстративным алгоритмом, который легко понять. Можно применить этот рабочий процесс к любому из пользовательских алгоритмов. Если вы хотите использовать конечная импульсная характеристика, рекомендуется использовать dsp.FIRFilter Системный объект в DSP System Toolbox. Этот объект запускается намного быстрее, чем номера бенчмарков, представленные в этом примере, без необходимости генерации кода.

Похожие темы