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