生成されたスタンドアロン コードでのマルチスレッド アクセスの FFTW 計画との同期
この例は、マルチスレッド アクセスが FFTW 計画プロセスと同期されるスタンドアロン コード (スタティック ライブラリ、ダイナミック リンク ライブラリまたは実行可能プログラム) を生成する方法を示します。
次の条件のすべてが満たされている場合、コード ジェネレーターは FFTW ライブラリ呼び出しを作成します。
MATLAB® コードが関数
fft
、fft2
、fftn
、ifft
、ifft2
またはifftn
のいずれかを呼び出している。スタンドアロン C/C++ コードを生成している。
FFTW ライブラリのインストール (Version 3.2 以上) にアクセスできる。
coder.fftw.StandaloneFFTW3Interface
から派生する FFT ライブラリ コールバック クラスで FFTW ライブラリ インストールを指定する。CustomFFTCallback
構成パラメーターをコールバック クラスの名前に設定している。MATLAB Coder™ アプリで、[カスタム FFT ライブラリのコールバック] 設定を使用します。
複数のスレッドがその FFTW ライブラリを呼び出す場合、生成されたコードは FFTW 計画プロセスへの同時アクセスを行わないようにしなければなりません。FFTW 計画へのアクセスを同期するには、FFT ライブラリ コールバック クラスで、lock
メソッドと unlock
メソッドを実装します。また、ロックまたはミューテックスを管理する C コードを提供しなければなりません。OpenMP、pthreads および C++ 標準ライブラリ (C++ 11 以降) などの多くのライブラリではロックが提供されています。次の例では、lock
メソッドと unlock
メソッドの実装方法を示し、C コードのサポートを提供します。ロックを管理するために、この例では OpenMP ライブラリを使用します。
前提条件
開始する前に、スタンドアロン コードで FFTW ライブラリ呼び出しを生成する基本的なワークフローについては、生成されたスタンドアロン コードでの FFTW ライブラリ呼び出しを使用した高速フーリエ変換の高速化を参照してください。
以下が必要です。
インストールされている FFTW ライブラリへのアクセス。
OpenMP ライブラリをサポートするコンパイラ。pthreads などの別のライブラリを使用するには、サポートされる C コードを適宜変更します。
MATLAB 関数の作成
高速フーリエ変換を parfor
ループ内部で呼び出す MATLAB 関数 mycustomfft
を記述します。
function y = mycustomfft() %#codegen t = 0:1/50:10-1/50; x = sin(2*pi*15*t) + sin(2*pi*20*t); y = fft(x); parfor k = 1:100 y = y + ifft(x+k); end
サポート 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
ダイナミック リンク ライブラリの生成
ダイナミック リンク ライブラリの生成用にコード生成構成オブジェクトを作成します。
cfg = coder.config('dll');
FFT コールバック クラス
myfftcb
を使用するコード生成を構成します。cfg.CustomFFTCallback = 'myfftcb';
サポート C コードをビルドに含めます。
cfg.CustomSource = 'mylock.c';
初期化コードでロック初期化関数への呼び出しを生成します。
cfg.CustomInitializer = 'mylock_initialize();';
ライブラリを生成します。
この例では OpenMP ライブラリを使用します。したがって、codegen -config cfg mycustomfft -report
EnableOpenMP
構成パラメーターがtrue
であるか、OpenMP フラグを手動でコンパイラに渡さなければなりません。既定では、EnableOpenMP
パラメーターはtrue
です。
MATLAB Coder アプリでの構成パラメーターの指定
MATLAB Coder アプリの前述の例の場合、次のプロジェクト設定を使用します。
FFT ライブラリ コールバック クラスを指定するために、[カスタム FFT ライブラリのコールバック] を
myfftcb
に設定します。含める C コードを指定するために、[追加ソース ファイル] を
mylock.c
に設定します。初期化コードで
mylock_initialize
への呼び出しの生成を指定するには、[初期化関数] をmylock_initialize();
に設定します。
参考
coder.ceval
| coder.fftw.StandaloneFFTW3Interface