Оптимизация — Эффективное 2D БПФ реальных входных данных фиксированной длины в C / Stack Overflow

Я разрабатываю алгоритм, который несколько раз вызывает функцию FFT. У меня есть несколько временных ограничений (желательно в режиме реального времени), поэтому мне нужно минимизировать время, затрачиваемое на каждый вызов FFT.

Я работаю с библиотекой OpenCV, и я уже реализовал свой код двумя различными подходами:

  • Использование библиотеки FFTW. Управление данными / памятью + FFT (8 мс) = 14 мс (в среднем флаг FFT_MEASURE).
  • Использование функции OpenCV FFT. Управление данными / памятью + FFT (21 мс) = 23 мс (в среднем).

Поскольку мои входные данные всегда фиксируются как реальное изображение 512×512 пикселей, как вы думаете, если я сам реализую алгоритм FFT, основанный на математическом определении DFT, сохраняя таблицы синусов / косинусов, я смогу добиться лучшей производительности, или библиотека FFTW действительно очень оптимизирован? Есть идеи получше?

Все идеи и предложения будут по достоинству оценены. В настоящее время я не рассматриваю параллелизацию или реализацию GPU.

Спасибо

Обновить:

Система: Процессор Intel Xeon 5130 с частотой 2,0 ГГц в Windows 7, Visual Studio 10.0 и FFTW 3.3.3 (скомпилировано в соответствии с инструкциями на сайте), OpenCV 2.4.3.

Пример кода для вызова FFT с FFTW (вход: OpenCV Mat CV_32F (1 канал, тип с плавающей запятой), выход OpenCV Mat CV_32FC2 (2 канала, тип с плавающей запятой):

float           *im_data;

fftwf_complex    *data_in;
fftwf_complex    *fft;

fftwf_plan       plan_f;

int             i, j, k;

int height=I.rows;
int width=I.cols;
int N=height*width;float* outdata = new float[2*N];
im_data = ( float* ) I.data;

data_in = ( fftwf_complex* )fftwf_malloc( sizeof( fftwf_complex ) * N );
fft     = ( fftwf_complex* )fftwf_malloc( sizeof( fftwf_complex ) * N );

plan_f = fftwf_plan_dft_2d( height , width , data_in , fft ,  FFTW_FORWARD ,  FFTW_MEASURE );

for(int i = 0,k=0; i < height; ++i) {
float* row = I.ptr<float>(i);
for(int j = 0; j < width; j++) {
data_in[k][0]=(float)row[j];
data_in[k][1] =(float)0.0;
k++;
}
}

fftwf_execute( plan_f );

int width2=2*width;
// writing output matrix: RealFFT[0],ImaginaryFFT[0],RealFFT[1],ImaginaryFFT[1],...
for( i = 0, k = 0 ; i < height ; i++ ) {
for( j = 0 ; j < width2 ; j++ ) {

outdata[i * width2 + j] = ( float )fft[k][0];
outdata[i * width2 + j+1] = ( float )fft[k][1];
j++;
k++;
}
}

Mat fft_I(height,width,CV_32FC2,outdata);

fftwf_destroy_plan( plan_f );
fftwf_free( data_in );
fftwf_free( fft );return fft_I;

4

Решение

Ваше время FFT с FFTW кажется очень высоким. Чтобы получить лучшее из FFTW с FFT фиксированного размера, вы должны сгенерировать план, используя FFTW_PATIENT пометить, а затем в идеале сохранить сгенерированную «мудрость» для последующего повторного использования. Вы можете генерировать мудрость либо из собственного кода, либо используя FFTW-мудрость инструмент.

3

Другие решения

БПФ от Библиотека Intel Math Kernel (отдельно от компилятора Intel) в большинстве случаев работает быстрее, чем FFTW. Я не знаю, будет ли достаточно улучшения в вашем случае, чтобы оправдать цену.

Я согласен с остальными, что использование собственного БПФ, вероятно, не является хорошим использованием вашего времени (если вы не хотите научиться делать это). Доступные реализации FFT (FFTW, MKL) были так точно настроены за многие годы. Я не говорю, что вы не можете добиться большего успеха, но это, вероятно, потребует много работы и времени для незначительных выгод.

1

Поверьте мне, fftw действительно очень оптимизирован, есть очень маленький шанс, что вы можете сделать это лучше.

Какой компилятор вы использовали для компиляции fftw? Иногда компилятор от Intel дает лучшую производительность, чем gcc

0
По вопросам рекламы [email protected]