Main Content

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

展開を使用した MATLAB 関数からのマルチスレッド MEX ファイルの生成

この例では、関数 "dspunfold" を使用して、MATLAB® 関数からマルチスレッド MEX ファイルを生成する方法を説明します。

メモ: 以下は、現在のホスト コンピューターに、少なくとも 2 つの物理 CPU コアが搭載されていることを前提とします。ここに示されたスクリーンショット、高速化およびレイテンシの値は、8 つの物理 CPU コアをもつホスト コンピューターを使用して収集されました。

必要な MathWorks™ 製品:

  • DSP System Toolbox™

  • MATLAB® Coder™

はじめに

dspunfold は、展開技術を使用して、MATLAB 関数からマルチスレッド MEX ファイルを生成します。この MATLAB 関数は、状態がないアルゴリズム、または状態があるアルゴリズムを含むことができます。

dspunfold の使用

MATLAB 関数 spectralAnalysisExample について考えます。関数は以下のアルゴリズムを実行します。

1) 入力の片側スペクトル推定の計算

2) スペクトルの全高調波歪み (THD)、S/N 比 (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);                

アルゴリズムを高速化するための一般的なアプローチは、関数 codegen を使用した MEX ファイルの生成です。以下は、4096 件の double の入力を使用する場合にこれを実行する方法の例です。生成された MEX ファイル dspunfoldDCTExample_mex はシングルスレッドです。

codegen spectralAnalysisExample -args {(1:4096)'}
Code generation successful.

マルチスレッド MEX ファイルを生成するには、関数 dspunfold を使用します。引数 -s は spectralAnalysisExample のアルゴリズムに状態がないことを示します。

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

これにより、以下のファイルが生成されます。

  • マルチスレッド MEX ファイル spectralAnalysisExample_mt

  • シングルスレッド MEX ファイル spectralAnalysisExample_st (関数 codegen を使用して得た MEX ファイルと同一)

  • 自己診断アナライザー関数 spectralAnalysisExample_analyzer

マルチスレッド MEX ファイルの高速化をシングルスレッド MEX ファイルと比較して測定するには、サンプル関数 dspunfoldBenchmarkSpectrumExample を参照してください。

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);

dspunfoldBenchmarkSpectrumExample は、spectralAnalysisExample_stspectralAnalysisExample_mt が 'numFrames' フレームを処理するときの実行時間を測定します。最後に高速化率が表示されます。これは、マルチスレッド MEX ファイルの実行時間とシングルスレッド MEX ファイルの実行時間との比になります。

dspunfoldBenchmarkSpectrumExample;
Speedup = 0.8x

高速化率は、反復の値を増やすことで、さらに向上する可能性があります。これについては後で説明します。

DSP 展開によって、複数の信号フレームのバッファリングとその後の並行処理を、複数のコアを使用して行うマルチスレッド MEX ファイルが生成されます。この処理には、いくらかの確定的な出力レイテンシが含まれます。'help spectralAnalysisExample_mt' を実行すると、マルチスレッド MEX ファイルに関する詳細情報が表示されますが、その中には出力レイテンシの値もあります。この例の場合、マルチスレッド MEX ファイルの出力には、その入力に比べて 16 フレーム分のレイテンシがあります。シングルスレッド MEX ファイルではこれはありません。以下は、dspunfoldShowLatencySpectrumExample によって生成されたプロットです。このプロットには、シングルスレッドの MEX ファイルとマルチスレッドの MEX ファイルの出力が表示されます。マルチスレッド MEX の出力が、シングルスレッド MEX と比較して 16 フレーム分遅れていることに注意してください。

dspunfoldShowLatencySpectrumExample;

Figure spectralAnalysisExample_mt output latency contains an axes object. The axes object with title Output latency is 8 frames, xlabel Frame index, ylabel THD contains 3 objects of type line. These objects represent Single-threaded MEX, Multi-threaded MEX, Multi-threaded MEX shifted by 8 frames.

生成されたアナライザーによる結果のマルチスレッド MEX の検証

dspunfold を使用してマルチスレッド MEX ファイルを作成すると、シングルスレッド 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.mexa64. For best results, please refrain from interacting with the computer and stop other processes until the analyzer is done.
Latency = 8 frames
Speedup = 0.8x
ans = struct with fields:
    Latency: 8
    Speedup: 0.8199
       Pass: 1

アナライザーに対する各入力は、MEX ファイル dspunfoldFIRExample_mt の入力に対応します。各入力の長さ (最初の次元) が期待される長さより大きいことに注目してください。たとえば、dspunfoldFIRExample_mt では、最初の入力に 4,096 件の double から成るフレームが必要ですが、spectralAnalysisExample_analyzer には 4096*10 サンプルが提供されています。アナライザーはこの入力を 4096 サンプルの 10 フレームとして解釈します。アナライザーは、マルチスレッドの MEX ファイルとシングルスレッドの MEX ファイルの出力が一致するかどうかチェックする間、これらの 10 個の入力フレームを交代で入れ替えます (循環方式)。

メモ: アナライザーが、マルチスレッド MEX とシングルスレッド MEX の間の数値の一致を正確にチェックできるように、各入力に、異なる値をもつフレームを少なくとも 2 つ与えることをお勧めします。

状態値と反復値の指定

スペクトル推定のスペクトルの平均長を 1 ではなく 4 に設定して、スペクトルの測定例を変更してみましょう。スペクトル推定は現在の推定と以前の 3 つの推定のランニング平均になっています。このアルゴリズムでは、状態長が 3 フレームとなっています。MATLAB 関数 spectralAnalysisWithStatesExample には変更されたアルゴリズムが含まれています。

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 ファイルを作成するには、2 つの FIR フィルターに対応した状態長を与えなければなりません。dspunfold を呼び出すときに -s 3 と指定した場合、状態長が 3 フレームを超えないことを示します。

dspunfold の呼び出し時に、与えられた反復 (-r) を増やすことでさらに高速化率が向上します。反復の既定値は 1 です。この値を増やすと、マルチスレッド MEX がフレームの処理を開始する前により多くのフレームを内部でバッファリングするようになり、マルチスレッドの効果が向上しますが、代わりに出力レイテンシは増加します。許容される最大状態長は (threads-1)*Repetition*FrameSize フレームであることにも注意してください。指定した状態長がその値を超える場合、dspunfold はシングルスレッド MEX に戻ります。レイテンシがアプリケーションで許容される場合、反復値を大きくすることにより長いステートをもつマルチスレッド MEX を生成できます。

以下のコマンドは、反復値 5 と 3 フレームの状態長を使用してマルチスレッド MEX 関数を生成します。

dspunfold spectralAnalysisWithStatesExample -args {(1:4096)'} -s 3 -r 5
State length: 3 frames, Repetition: 5, Output latency: 40 frames, Threads: 4
Analyzing: spectralAnalysisWithStatesExample.m
Creating single-threaded MEX file: spectralAnalysisWithStatesExample_st.mexa64
Creating multi-threaded MEX file: spectralAnalysisWithStatesExample_mt.mexa64
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.mexa64. For best results, please refrain from interacting with the computer and stop other processes until the analyzer is done.
Latency = 40 frames
Speedup = 0.8x
ans = struct with fields:
    Latency: 40
    Speedup: 0.7592
       Pass: 1

シミュレーションの例

関数 dspunfoldNoisySineExample は、マルチスレッド MEX を使ってノイズを含んだ正弦波のスペクトル特性を推定する方法を示します。測定は時間スコープ上でプロットされます。マルチスレッド MEX のパフォーマンスを MATLAB シミュレーションおよびシングルスレッド MEX のパフォーマンスと比較します。プロットによりオーバーヘッドが持ちこまれ、テストベンチが入力信号を生成しても、マルチスレッド MEX のゲインが明らかです。

dspunfoldNoisySineExample

MATLAB Sim/Single-threaded MEX speedup: 3.9
MATLAB Sim/Multi-threaded MEX speedup: 3.9

参照

[1] DSP unfolding on Wikipedia : Unfolding (DSP implementation)