Main Content

MATLAB Function ブロックからの生成コード内のマルチスレッド FFTW 計画の同期

この例では、MATLAB Function ブロックからの生成コード内の FFTW ライブラリ呼び出しについて、FFTW 計画プロセスへのマルチスレッド アクセスを同期するコードを生成する方法を示します。

次の条件のすべてが満たされている場合、コード ジェネレーターは FFTW ライブラリ呼び出しを作成します。

  • MATLAB Function ブロックが、fftfft2fftnifftifft2、または 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 ブロックを使用するモデルの作成

  1. Simulink® モデルを作成し、それに MATLAB Function ブロックを追加します。

  2. 次のコードを 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
    

  3. 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

コード生成パラメーターの設定とモデルの作成

  1. lock メソッドと unlock メソッドで呼び出される FFTW コールバック クラスと C コードを使用するようコード生成を設定します。初期化コードで mylock_initialize の呼び出しを生成するようにコード生成を設定します。

    [コンフィギュレーション パラメーター] ダイアログ ボックスで、以下の操作を実行します。

    • [カスタム FFT ライブラリのコールバック]myfftcb に設定する。

    • [コード生成]、[カスタム コード][追加のビルド情報] で、[ソース ファイル]mylock.c に設定する。

    • [コード生成]、[カスタム コード][生成時に挿入するカスタム C コード] で、[初期化関数]mylock_initialize(); に設定する。

  2. モデルを作成します。

参考

関連するトピック

外部の Web サイト