exponenta event banner

Создание многопоточного MEX-файла из функции MATLAB с помощью развертки

В этом примере показано, как использовать функцию dspunfold для создания многопоточного MEX-файла из функции MATLAB.

ПРИМЕЧАНИЕ: Далее предполагается, что текущий хост-компьютер имеет по крайней мере 2 физических ядра ЦП. Представленные снимки экрана, значения ускорения и задержки были собраны с помощью главного компьютера с 8 физическими ядрами ЦП.

Необходимые MathWorks™ продукты:

  • Toolbox™ системы DSP

  • MATLAB ® Coder™

Введение

dspunfold генерирует многопоточный MEX-файл из функции MATLAB с использованием технологии развертывания. Эта функция MATLAB может содержать алгоритм без состояния (не имеет состояний) или с состоянием (имеет состояния).

Используя dspunfold

Рассмотрим пример спектрального анализа функции MATLAB. Функция выполняет следующий алгоритм:

1) Вычислить одностороннюю оценку спектра входного сигнала

2) Вычислите суммарные гармонические искажения (THD), отношение сигнал/шум (SNR), отношение сигнал/шум и искажения (SINAD) и ложный свободный динамический диапазон (SFDR) спектра

type spectralAnalysisExample
function [THD,SNR,SINAD,SFDR] = spectralAnalysisExample(x)
%

% Copyright 2015-2016 The MathWorks, Inc.

persistent powerSpectrum
if isempty(powerSpectrum)
  powerSpectrum  = dsp.SpectrumEstimator('FrequencyRange','onesided',...
                              'SampleRate',8000,...
                              'SpectralAverages',1);  
end

% Get one-sided spectrum estimate
Pxx = powerSpectrum(x); 

% Compute measurements
[amp, harmSum, totalNoise, maxSpur] = ...
    getHarmonicDistortion(...
    getFrequencyVector(powerSpectrum), Pxx, getRBW(powerSpectrum), 6);

THD   = 10*log10(harmSum/amp(1));              
SNR   = 10*log10(amp(1)/totalNoise);               
SINAD = 10*log10(amp(1)/(harmSum + totalNoise));
SFDR  = 10*log10(amp(1)/maxSpur);                

Для ускорения алгоритма общим подходом является генерация MEX-файла с использованием функции кодегена. Ниже приведен пример того, как это сделать при использовании ввода 4096 дублей. Созданный файл MEX, dspunfoldDCTExample_mex, является однопоточным.

codegen spectralAnalysisExample -args {(1:4096)'}

Чтобы создать многопоточный MEX-файл, используйте функцию dspunfold. Аргумент -s указывает, что алгоритм в спектральном анализе Example не имеет состояний.

dspunfold spectralAnalysisExample -args {(1:4096)'} -s 0
State length: 0 frames, Repetition: 1, Output latency: 16 frames, Threads: 8
Analyzing: spectralAnalysisExample.m
Creating single-threaded MEX file: spectralAnalysisExample_st.mexmaci64
Creating multi-threaded MEX file: spectralAnalysisExample_mt.mexmaci64
Creating analyzer file: spectralAnalysisExample_analyzer.p

При этом будут созданы следующие файлы:

  • многопоточный MEX-файл, spectralAnalysisExample_mt

  • однопоточный файл MEX, spectralAnalysisExample_st (который идентичен файлу MEX, полученному с помощью функции codegen)

  • функция самодиагностического анализатора, spectralAnalysisExample_analyzer

Чтобы измерить скорость многопоточного MEX-файла относительно однопоточного MEX-файла, см. пример функции dspunfoldBenchmarkПример:

type dspunfoldBenchmarkSpectrumExample
function dspunfoldBenchmarkSpectrumExample
% Function used to measure the speedup of the multi-threaded MEX file
% obtained using dspunfold vs the single-threaded MEX file

% Copyright 2015 The MathWorks, Inc.

clear spectralAnalysisExample_st;  % for benchmark precision purpose
clear spectralAnalysisExample_mt;  % for benchmark precision purpose

numFrames = 1e5;
inputFrame = (1:4096)';

% exclude first run from timing measurements
spectralAnalysisExample_st(inputFrame); 
tic;  % measure execution time for the single-threaded MEX
for frame = 1:numFrames 
    spectralAnalysisExample_st(inputFrame);
end
timeSingleThreaded = toc;

% exclude first run from timing measurements
spectralAnalysisExample_mt(inputFrame); 
tic;  % measure execution time for the multi-threaded MEX
for frame = 1:numFrames
    spectralAnalysisExample_mt(inputFrame);
end
timeMultiThreaded = toc;
fprintf('Speedup = %.1fx\n',timeSingleThreaded/timeMultiThreaded);

dspunfoldBenchmarkExampleПример измеряет время выполнения spectralAnalysisExample_st и spectralAnalysisExample_mt для обработки кадров numFrames. Наконец, он печатает ускорение, которое представляет собой соотношение между временем выполнения многопоточного файла MEX и временем выполнения однопоточного файла MEX.

dspunfoldBenchmarkSpectrumExample;
Speedup = 2.0x

Ускорение может быть еще больше улучшено за счет увеличения значения повторения, которое будет обсуждаться позже.

Развертка DSP генерирует многопоточный MEX-файл, который буферизирует множество сигнальных кадров, а затем обрабатывает эти кадры одновременно, используя множество ядер. Этот процесс вводит некоторую детерминированную задержку вывода. При выполнении "help spectralAnalysisExample_mt' отображается дополнительная информация о многопоточном MEX-файле, одним из которых является значение задержки вывода. В этом примере выходной сигнал многопоточного MEX-файла имеет задержку 16 кадров относительно его входного сигнала, что не относится к однопоточному MEX-файлу. Ниже приведен график, сгенерированный dspunfoldStartLatencyExampleExample, который отображает выходные данные однопоточных и многопоточных MEX-файлов. Обратите внимание, что выходной сигнал многопоточного MEX задерживается на 16 кадров относительно выходного сигнала однопоточного MEX.

dspunfoldShowLatencySpectrumExample;

Проверка результирующего многопоточного MEX с помощью созданного анализатора

При создании многопоточного MEX-файла с использованием dspunfold, однопоточный MEX-файл также создается вместе с функцией анализатора. В этом примере spectralAnalysisExample_analyzer имя анализатора.

Целью анализатора является обеспечение быстрого способа измерения скорости многопоточного MEX относительно однопоточного MEX, а также проверка соответствия выходов многопоточного MEX и однопоточного MEX. Выходные данные обычно не совпадают, если указано неверное значение длины состояния.

Ниже приведен пример выполнения анализатора для многопоточного файла MEX, dspunfoldFIRExample_mt.

Fs = 8000;
NumFrames = 10;
t  = (1/Fs) * (0:4096*NumFrames-1); t = t.';
f = 100;
x  = sin(2*pi*f*t) + .01 * randn(size(t));
spectralAnalysisExample_analyzer(x)
Analyzing multi-threaded MEX file spectralAnalysisExample_mt.mexmaci64. For best results, please refrain from interacting with the computer and stop other processes until the analyzer is done.
Latency = 16 frames
Speedup = 2.3x

ans = 

  struct with fields:

    Latency: 16
    Speedup: 2.3114
       Pass: 1

Каждый вход анализатора соответствует входам файла dspunfoldFIRExample_mt MEX. Обратите внимание, что длина (первый размер) каждого ввода больше ожидаемой длины. Например, для первого ввода dspunfoldFIRExample_mt ожидает кадр из 4096 двойников, в то время как для 4096 были предоставлены выборки 10 * spectralAnalysisExample_analyzer. Анализатор интерпретирует этот входной сигнал как 10 кадров 4096 выборок. Анализатор чередует эти 10 входных кадров (циклически), проверяя, совпадают ли выходы многопоточных и однопоточных файлов MEX.

ПРИМЕЧАНИЕ: Чтобы анализатор правильно проверял численное соответствие между многопоточным MEX и однопоточным MEX, рекомендуется предоставить не менее 2 кадров с различными значениями для каждого входа.

Определение значений состояния и повтора

Давайте изменим пример спектрального измерения, установив спектральную среднюю длину спектральной оценки равной 4 вместо 1. Оценка спектра теперь представляет собой текущее среднее текущей оценки и трех предыдущих оценок. Этот алгоритм имеет длину состояния 3 кадра. Функция MATLAB spectralAnalyityWeyS.Example содержит модифицированный алгоритм:

type spectralAnalysisWithStatesExample
function [THD,SNR,SINAD,SFDR] = spectralAnalysisWithStatesExample(x)
%

% Copyright 2015-2016 The MathWorks, Inc.

persistent powerSpectrum
if isempty(powerSpectrum)
  powerSpectrum  = dsp.SpectrumEstimator('FrequencyRange','onesided',...
                              'SampleRate',8000,...
                              'SpectralAverages',4);  
end

% Get one-sided spectrum estimate
Pxx = powerSpectrum(x); 

% Compute measurements
[amp, harmSum, totalNoise, maxSpur] = ...
    getHarmonicDistortion(...
    getFrequencyVector(powerSpectrum), Pxx, getRBW(powerSpectrum), 6);

THD   = 10*log10(harmSum/amp(1));              
SNR   = 10*log10(amp(1)/totalNoise);               
SINAD = 10*log10(amp(1)/(harmSum + totalNoise));
SFDR  = 10*log10(amp(1)/maxSpur);                

Чтобы построить многопоточный MEX-файл, мы должны предоставить длину состояния, соответствующую двум фильтрам FIR. Указание -s 3 при вызове функции «дспунфолд» указывает на то, что длина состояния не превышает 3 кадров.

Ускорение может быть увеличено еще больше за счет увеличения повторения (-r), обеспечиваемого при вызове dspunfold. Значение повторения по умолчанию - 1. Увеличение этого значения делает многопоточный MEX-буфер больше кадров внутри, прежде чем он начнет их обработку, увеличивая эффективность многопоточности, но за счет более высокой задержки вывода. Также следует отметить, что максимально допустимая длина состояния равна (threads-1) * Repertion * FrameSize кадров. Если указанная длина состояния превышает это значение, функция dspunfold возвращается к однопоточному MEX. Если задержка может допускаться приложением, увеличение значения повторения позволяет генерировать многопоточный MEX с более длинным состоянием.

Команда ниже генерирует многопоточную функцию MEX, используя значение повторения 5 и длину состояния 3 кадра:

dspunfold spectralAnalysisWithStatesExample -args {(1:4096)'} -s 3 -r 5
State length: 3 frames, Repetition: 5, Output latency: 80 frames, Threads: 8
Analyzing: spectralAnalysisWithStatesExample.m
Creating single-threaded MEX file: spectralAnalysisWithStatesExample_st.mexmaci64
Creating multi-threaded MEX file: spectralAnalysisWithStatesExample_mt.mexmaci64
Creating analyzer file: spectralAnalysisWithStatesExample_analyzer.p

Анализатор может использоваться для проверки числовых результатов многопоточного MEX и предоставления информации об ускорении и задержке:

L = 4096;
NumFrames = 10;
sine  = dsp.SineWave('SamplesPerFrame',L * NumFrames,'SampleRate',8000);
x     = sine() + 0.01 * randn(L * NumFrames, 1);
spectralAnalysisWithStatesExample_analyzer(x)
Analyzing multi-threaded MEX file spectralAnalysisWithStatesExample_mt.mexmaci64. For best results, please refrain from interacting with the computer and stop other processes until the analyzer is done.
Latency = 80 frames
Speedup = 2.4x

ans = 

  struct with fields:

    Latency: 80
    Speedup: 2.4061
       Pass: 1

Пример моделирования

Функция dspunfoldNoisySineПример демонстрирует использование многопоточного MEX для оценки спектральных характеристик шумовой синусоидальной волны. Измерения нанесены на график во временном диапазоне. Производительность многопоточного MEX сравнивается с имитацией MATLAB и производительностью однопоточного MEX. Коэффициенты усиления многопоточного MEX все еще очевидны даже в случае служебной информации, создаваемой построением графика и формированием входного сигнала тестового модуля.

dspunfoldNoisySineExample
MATLAB Sim/Single-threaded MEX speedup: 2.3
MATLAB Sim/Multi-threaded MEX speedup: 3.1

Ссылки

DSP разворачивается в Википедии: Разворачивание (реализация DSP)