Синхронизируйте многопоточный доступ к FFTW, планирующему в сгенерированном автономном коде

Этот пример показывает, как сгенерировать автономный код (статическая библиотека, динамически подключаемая библиотека или исполняемая программа), который синхронизирует многопоточный доступ к процессу планирования FFTW.

Генератор кода производит вызовы библиотеки FFTW, когда все эти условия верны:

  • Ваш код MATLAB® вызывает один из этих functions:fft, fft2, fftn, ifft, ifft2 или ifftn.

  • Вы генерируете автономный код C/C++.

  • У вас есть доступ к установке библиотеки FFTW, версии 3.2 или позже.

  • Вы задаете установку библиотеки FFTW в классе обратного вызова библиотеки FFT, который выводит от coder.fftw.StandaloneFFTW3Interface.

  • Вы устанавливаете параметр конфигурации CustomFFTCallback на имя класса обратного вызова. В приложении MATLAB Coder™ используйте установку обратного вызова библиотеки Custom FFT.

Если несколько потоков вызывают библиотеку FFTW, то сгенерированный код должен предотвратить параллельный доступ к процессу планирования FFTW. Чтобы синхронизировать доступ к планированию FFTW, в вашем классе обратного вызова библиотеки FFT, реализуют методы unlock и lock. Необходимо также обеспечить код С, который управляет блокировкой или взаимным исключением. Многие библиотеки, такие как OpenMP, pthreads, и библиотека стандарта C++ (C++ 11 и позже) обеспечивают блокировки. Этот пример показывает, как реализовать lock и методы unlock и обеспечить код С поддержки. Чтобы управлять блокировкой, этот пример пользуется библиотекой OpenMP.

Предпосылки

Прежде чем вы запустите для основного рабочего процесса для генерации вызовов библиотеки FFTW в автономном коде, смотрите, Ускоряют Быстрые преобразования Фурье в Сгенерированном Автономном Коде при помощи Вызовов Библиотеки FFTW.

Вы должны иметь:

  • Доступ к установленной библиотеке FFTW.

  • Компилятор, который поддерживает библиотеку OpenMP. Чтобы пользоваться различной библиотекой, такой как pthreads, изменяют код С поддержки соответственно.

Создайте функцию MATLAB

Запишите функции MATLAB mycustomfft, который вызывает функцию быстрого преобразования Фурье в цикле parfor:

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, которые инициализируют, устанавливают и сбрасывают блокировку. Этот пример пользуется библиотекой OpenMP, чтобы управлять блокировкой. Для различной библиотеки измените код соответственно.

  • Создайте файл 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

Запишите класс обратного вызова библиотеки БПФа

Запишите классу обратного вызова БПФа myfftcb что:

  • Задает библиотеку FFTW.

  • lock реализаций и методы unlock, которые вызывают код С поддержки, чтобы управлять доступом к планированию FFTW.

Используйте этот класс в качестве шаблона. Замените 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. Сконфигурируйте генерацию кода, чтобы использовать класс обратного вызова БПФа myfftcb.

    cfg.CustomFFTCallback = 'myfftcb';
    
  3. Включайте код С поддержки в сборку.

    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, установите обратный вызов библиотеки Custom FFT на myfftcb.

  • Чтобы задать код С, чтобы включать, установите Дополнительные исходные файлы на mylock.c c.

  • Чтобы задать генерацию вызова mylock_initialize в коде инициализации, установите, Инициализируют функцию к mylock_initialize();.

Смотрите также

|

Похожие темы

Внешние веб-сайты

Была ли эта тема полезной?