Примечание
Тесты в этом примере были измерены на машине с четырьмя физическими ядрами.
В этом примере показано, как ускорить алгоритм обработки сигналов в MATLAB ® с помощью codegen (Кодер MATLAB) и dspunfold функции. Можно создать исполняемый файл MATLAB (функция MEX) из всей функции MATLAB или отдельных частей функции MATLAB. При запуске функции MEX вместо исходного кода MATLAB скорость моделирования может значительно увеличиться. Для генерации эквивалента MEX алгоритм должен поддерживать генерацию кода.
Использовать codegen (Кодер MATLAB), необходимо установить Coder™ MATLAB. Использовать dspunfold, необходимо установить кодер MATLAB и системный Toolbox™ DSP.
Использовать dspunfold в Windows и Linux необходимо использовать компилятор, поддерживающий интерфейс приложения Open Multi-Processing (OpenMP). См. раздел Поддерживаемые компиляторы.
Рассмотрим простой алгоритм FIR-фильтра для ускорения. Копировать 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 или C++. Увеличение скорости масштабируется с количеством ядер на хост-машине.
Функция фильтра FIR в этом примере является только иллюстративным алгоритмом, который легко понять. Этот рабочий процесс можно применить к любым пользовательским алгоритмам. Если требуется использовать фильтр FIR, рекомендуется использовать dsp.FIRFilter Системный объект в панели системных инструментов DSP. Этот объект работает намного быстрее, чем контрольные номера, представленные в этом примере, без необходимости создания кода.