В этом примере показано, как сгенерировать автономный код (статическая библиотека, динамически связанная библиотека или исполняемая программа), который синхронизирует многопоточный доступ к процессу планирования 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