В этом примере показано, как сгенерировать автономный код (статическая библиотека, динамически связанная библиотека или исполняемая программа), который синхронизирует многопоточный доступ к процессу планирования FFTW.
Генератор кода производит вызовы библиотеки FFTW, когда все эти условия верны:
Ваш MATLAB® код вызывает одну из следующих функций:fft, fft2, fftn, ifft, ifft2, или ifftn.
Вы генерируете автономный код C/C + +.
У вас есть доступ к установке библиотеки FFTW версии 3.2 или более поздней.
Установка библиотеки FFTW задается в классе коллбэка библиотеки FFT, который является производным от coder.fftw.StandaloneFFTW3Interface.
Вы устанавливаете CustomFFTCallback параметр конфигурации с именем класса коллбэка. В приложении MATLAB Coder™ используйте настройку Custom FFT library callback.
Если несколько потоков вызывают библиотеку FFTW, то сгенерированный код должен препятствовать параллельному доступу к процессу планирования FFTW. Чтобы синхронизировать доступ к планированию FFTW, в классе коллбэка библиотеки FFT реализуйте lock и unlock методы. Вы также должны предоставить код С, который управляет блокировкой или мьютексом. Блокировки обеспечивают многие библиотеки, такие как OpenMP, pthreads и стандартная библиотека C++ (C++ 11 и более поздние версии). В этом примере показано, как реализовать lock и unlock методы и обеспечивают поддержку кода С Для управления блокировкой в этом примере используется библиотека OpenMP.
Прежде чем вы начнете, для базового рабочего процесса для генерации вызовов библиотеки FFTW в автономном коде, смотрите Ускорение быстрых преобразований Фурье в Сгенерированном Автономном Коде при Помощи Вызовов Библиотеки FFTW.
Вы должны иметь:
Доступ к установленной библиотеке FFTW.
Компилятор, поддерживающий библиотеку OpenMP. Чтобы использовать другую библиотеку, такую как pthreads, измените соответствующий поддерживающий код С
Написание функции 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
Запись класса коллбэка FFT 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
Создайте объект строения генерации кода для генерации динамически связанной библиотеки.
cfg = coder.config('dll');Сконфигурируйте генерацию кода, чтобы использовать класс коллбэка FFT myfftcb.
cfg.CustomFFTCallback = 'myfftcb';
Включите в сборку поддерживающий код С
cfg.CustomSource = 'mylock.c';Сгенерируйте вызов функции инициализации блокировки в коде инициализации.
cfg.CustomInitializer = 'mylock_initialize();';Сгенерируйте библиотеку.
codegen -config cfg mycustomfft -report
EnableOpenMP параметр конфигурации должен быть true или необходимо вручную передать флаги OpenMP компилятору. По умолчанию в EnableOpenMP параметр true.
Для предыдущего примера в приложении MATLAB Coder используйте следующие настройки проекта:
Чтобы задать класс коллбэка библиотеки FFT, установите Custom FFT library callback равным myfftcb.
Чтобы задать код С, который будет включен, установите Additional source files равным mylock.c.
Чтобы задать генерацию вызова для mylock_initialize в коде инициализации установите Initialize function mylock_initialize();.
coder.ceval | coder.fftw.StandaloneFFTW3Interface