Я получаю ускорение для 2 ядер даже при n = 2 ^ 14, и после этого оно остается стабильно выше 1,5.Не забудьте запустить код несколько раз и выбросить первую часть, использованную для раскрутки.Современным ядрам нужно некоторое время, чтобы набрать полную скорость.
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <float.h>
#include "fftw3.h"
#include "omp.h"
/* Compute (K*L)%M accurately */
static double moda(int K, int L, int M)
{
return (double)(((long long)K * L) % M);
}
/* Initialize array x[N] with harmonic H */
static void init(fftw_complex *x, int N, int H)
{
double TWOPI = 6.2831853071795864769, phase;
int n;
for (n = 0; n < N; n++)
{
phase = moda(n,H,N) / N;
x[n][0] = cos( TWOPI * phase ) / N;
x[n][1] = sin( TWOPI * phase ) / N;
}
}
int main(int argc, char *argv[]) {
if(argc < 2) {
printf("Error : give args\n");
return 0;
}
int max_pow = atoi(argv[1]);
int p = 1;
#pragma omp parallel
{
#pragma omp single
{
p = omp_get_num_threads();
}
}
printf("%i\n", p);
fftw_plan forward_plan = 0;
fftw_complex *x = 0;
fftw_init_threads();
fftw_plan_with_nthreads(p);
for(int iter=1;iter<=2;iter++){
//throw away the first round, a couple of seconds is enough
for(int pw=12;pw<=max_pow;pw++){
int N = pow(2, pw);
int H = -N/2;
x = fftw_malloc(sizeof(fftw_complex)*N);
forward_plan = fftw_plan_dft(1, &N, x, x, FFTW_FORWARD, FFTW_MEASURE);
init(x, N, H);
double start_time = omp_get_wtime();
/*--------------ALG STARTS HERE --------------------------*/
for(int i=1;i<=5;i++){fftw_execute(forward_plan);}
/*--------------ALG ENDS HERE --------------------------*/
double end_time = omp_get_wtime();
printf("%i %lf\n", pw, (end_time - start_time)/5);
fftw_destroy_plan(forward_plan);
fftw_free(x);
}
}
return 0;
}
и
> gfortran -fopenmp fftw1d.c -lfftw3 -lfftw3_omp
> OMP_NUM_THREADS=2 ./a.out 24
результаты совпадают с -O3
и без него, поскольку библиотека уже скомпилирована.
Протестировано на четырехъядерном процессоре Intel (R) Core (TM) i7-3770 @ 3,40 ГГц