MATLAB Function ブロックからの生成コード内のマルチスレッド FFTW 計画の同期
この例では、MATLAB Function ブロックからの生成コード内の FFTW ライブラリ呼び出しについて、FFTW 計画プロセスへのマルチスレッド アクセスを同期するコードを生成する方法を示します。
次の条件のすべてが満たされている場合、コード ジェネレーターは FFTW ライブラリ呼び出しを作成します。
MATLAB Function ブロックが、
fft
、fft2
、fftn
、ifft
、ifft2
、またはifftn
のいずれかの関数を呼び出す。MATLAB Function ブロックを含むモデルの C/C++ コードを生成する。
FFTW ライブラリのインストール (Version 3.2 以上) にアクセスできる。
coder.fftw.StandaloneFFTW3Interface
から派生する FFT ライブラリ コールバック クラスで FFTW ライブラリ インストールを指定している。[カスタム FFT ライブラリのコールバック] コンフィギュレーション パラメーターをコールバック クラスの名前に設定している。
FFTW 呼び出しを含むコードを複数のスレッドで実行される外部コードに統合する場合は、FFTW 計画プロセスへの同時アクセスを回避しなければなりません。FFT ライブラリ コールバック クラスで、lock
メソッドと unlock
メソッドを実装します。また、ロックまたはミューテックスを管理する C コードを提供しなければなりません。OpenMP、pthreads および C++ 標準ライブラリ (C++ 11 以降) などの多くのライブラリではロックが提供されています。次の例では、lock
メソッドと unlock
メソッドの実装方法を示し、サポート C コードを提供します。ロックを管理するために、この例では OpenMP ライブラリを使用します。
前提条件
開始する前に、MATLAB Function ブロックの高速フーリエ変換に対して FFTW ライブラリ呼び出しを生成する基本ワークフローについては、MATLAB Function ブロックからの生成コード内の高速フーリエ変換の高速化を参照してください。
以下が必要です。
インストールされている FFTW ライブラリへのアクセス。
OpenMP ライブラリをサポートするコンパイラ。pthreads などの別のライブラリを使用するには、サポートされる C コードを適宜変更します。
FFT 関数を呼び出す MATLAB Function ブロックを使用するモデルの作成
Simulink® モデルを作成し、それに MATLAB Function ブロックを追加します。
次のコードを MATLAB Function ブロックに追加します。
function y = mycustomfft() t = 0:1/50:10-1/50; x = sin(2*pi*15*t) + sin(2*pi*20*t); y = fft(x); for k = 1:100 y = y + ifft(x+k); end
outport
ブロックを追加して MATLAB Function ブロックに接続します。
サポート C コードの記述
ロックを初期化、設定、設定解除する C 関数を記述します。この例では、ロックを管理するために OpenMP ライブラリを使用します。ライブラリが異なる場合は、それに応じてコードを変更してください。
次の C コードを含むファイル
mylock.c
を作成します。#include "mylock.h" #include "omp.h" static omp_nest_lock_t lockVar; void mylock_initialize(void) { omp_init_nest_lock(&lockVar); } void mylock(void) { omp_set_nest_lock(&lockVar); } void myunlock(void) { omp_unset_nest_lock(&lockVar); }
次を含むヘッダー ファイル
mylock.h
を作成します。#ifndef MYLOCK_H #define MYLOCK_H void mylock_initialize(void); void mylock(void); void myunlock(void); #endif
FFT ライブラリ コールバック クラスの作成
次のような FFT コールバック クラス myfftcb
を記述します。
FFTW ライブラリを指定する。
サポートする C コードを呼び出して FFTW 計画へのアクセスを制御する
lock
メソッドとunlock
メソッドを実装する。
このクラスをテンプレートとして使用します。fftwLocation
を FFTW ライブラリのインストール場所で置き換えます。
classdef myfftcb < coder.fftw.StandaloneFFTW3Interface methods (Static) function th = getNumThreads coder.inline('always'); th = int32(coder.const(1)); end function lock() coder.cinclude('mylock.h', 'InAllSourceFiles', true); coder.inline('always'); coder.ceval('mylock'); end function unlock() coder.cinclude('mylock.h', 'InAllSourceFiles', true); coder.inline('always'); coder.ceval('myunlock'); end function updateBuildInfo(buildInfo, ctx) fftwLocation = '\usr\lib\fftw'; includePath = fullfile(fftwLocation, 'include'); buildInfo.addIncludePaths(includePath); libPath = fullfile(fftwLocation, 'lib'); %Double libName1 = 'libfftw3-3'; [~, libExt] = ctx.getStdLibInfo(); libName1 = [libName1 libExt]; addLinkObjects(buildInfo, libName1, libPath, 1000, true, true); %Single libName2 = 'libfftw3f-3'; [~, libExt] = ctx.getStdLibInfo(); libName2 = [libName2 libExt]; addLinkObjects(buildInfo, libName2, libPath, 1000, true, true); end end end
コード生成パラメーターの設定とモデルの作成
lock
メソッドとunlock
メソッドで呼び出される FFTW コールバック クラスと C コードを使用するようコード生成を設定します。初期化コードでmylock_initialize
の呼び出しを生成するようにコード生成を設定します。[コンフィギュレーション パラメーター] ダイアログ ボックスで、以下の操作を実行します。
[カスタム FFT ライブラリのコールバック] を
myfftcb
に設定する。[コード生成]、[カスタム コード] の [追加のビルド情報] で、[ソース ファイル] を
mylock.c
に設定する。[コード生成]、[カスタム コード] の [生成時に挿入するカスタム C コード] で、[初期化関数] を
mylock_initialize();
に設定する。
モデルを作成します。
参考
coder.fftw.StandaloneFFTW3Interface