Main Content

生成されたスタンドアロン コードでのマルチスレッド アクセスの FFTW 計画との同期

この例は、マルチスレッド アクセスが FFTW 計画プロセスと同期されるスタンドアロン コード (スタティック ライブラリ、ダイナミック リンク ライブラリまたは実行可能プログラム) を生成する方法を示します。

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

  • MATLAB® コードが関数 fftfft2fftnifftifft2 または 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

ダイナミック リンク ライブラリの生成

  1. ダイナミック リンク ライブラリの生成用にコード生成構成オブジェクトを作成します。

    cfg = coder.config('dll');

  2. FFT コールバック クラス myfftcb を使用するコード生成を構成します。

    cfg.CustomFFTCallback = 'myfftcb';
    
  3. サポート C コードをビルドに含めます。

    cfg.CustomSource = 'mylock.c';

  4. 初期化コードでロック初期化関数への呼び出しを生成します。

    cfg.CustomInitializer = 'mylock_initialize();';

  5. ライブラリを生成します。

    codegen -config cfg mycustomfft -report
    この例では OpenMP ライブラリを使用します。したがって、EnableOpenMP 構成パラメーターが true であるか、OpenMP フラグを手動でコンパイラに渡さなければなりません。既定では、EnableOpenMP パラメーターは true です。

MATLAB Coder アプリでの構成パラメーターの指定

MATLAB Coder アプリの前述の例の場合、次のプロジェクト設定を使用します。

  • FFT ライブラリ コールバック クラスを指定するために、[カスタム FFT ライブラリのコールバック]myfftcb に設定します。

  • 含める C コードを指定するために、[追加ソース ファイル]mylock.c に設定します。

  • 初期化コードで mylock_initialize への呼び出しの生成を指定するには、[初期化関数]mylock_initialize(); に設定します。

参考

|

関連するトピック

外部の Web サイト