exponenta event banner

Синхронизация многопоточного планирования FFTW в коде, сгенерированном из функционального блока MATLAB

В этом примере показано, как создать код, синхронизирующий многопоточный доступ к процессу планирования FFTW для вызовов библиотеки FFTW в коде, сгенерированном из функционального блока MATLAB.

Генератор кода производит вызовы библиотеки FFTW при выполнении всех следующих условий:

  • Функциональный блок MATLAB вызывает одну из следующих функций:fft, fft2, fftn, ifft, ifft2, или ifftn.

  • Код C/C + + создается для модели, включающей функциональный блок MATLAB.

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

  • Установка библиотеки FFTW задается в классе обратного вызова библиотеки FFT, производном от coder.fftw.StandaloneFFTW3Interface.

  • Для параметра конфигурации Custom FFT library callback устанавливается имя класса обратного вызова.

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

Предпосылки

Перед началом работы см. раздел Ускорение быстрых преобразований Фурье в коде, сгенерированном из функционального блока MATLAB, для базового рабочего процесса генерации вызовов библиотеки FFTW для быстрых преобразований Фурье в функциональном блоке MATLAB.

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

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

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

Создание модели с функциональным блоком MATLAB, вызывающим функцию FFT

  1. Создайте модель Simulink ® и добавьте к ней функциональный блок MATLAB.

  2. Добавьте этот код в функциональный блок MATLAB.

    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.

Записать поддерживающий код C

Запишите функции C, которые инициализируют, устанавливают и отменяют блокировку. В этом примере для управления блокировкой используется библиотека OpenMP. Для другой библиотеки измените код соответствующим образом.

  • Создание файла mylock.c который содержит код 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.

  • Орудия lock и unlock методы, которые вызывают поддерживающий код C для управления доступом к планированию 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. Конфигурирование генерации кода для использования класса обратного вызова FFTW и кода C, вызываемого lock и unlock методы. Настройка генерации кода для генерации вызова mylock_initialize в коде инициализации.

    В диалоговом окне «Параметры конфигурации»:

    • Задать обратный вызов пользовательской библиотеки FFT для myfftcb.

    • В разделе «Создание кода» > «Пользовательский код» в разделе «Дополнительные сведения о построении» задайте для параметра «Исходные файлы» значение mylock.c.

    • В разделе «Создание кода» > «Пользовательский код» в разделе «Вставка пользовательского кода C в созданном» установите для функции «Инициализация» значение mylock_initialize();.

  2. Создайте модель.

См. также

Связанные темы

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