代码分析以fftw2.15为例,原代码在fftw/planner.c中
fftw_plan fftw_create_plan(int n, fftw_direction dir, int flags)
{
fftw_complex *tmp_in, *tmp_out;
fftw_plan p;
//如果falgs为FFTW_MEASURE,则评估几种不同的计算方案,寻找最优的方案
if (flags & FFTW_MEASURE) {
tmp_in = (fftw_complex *) fftw_malloc(2 * n * sizeof(fftw_complex));
if (!tmp_in)
return 0;
tmp_out = tmp_in + n;
//此处输入的tmp_in, tmp_out用于计算方案的耗时评估
p = fftw_create_plan_specific(n, dir, flags,
tmp_in, 1, tmp_out, 1);
fftw_free(tmp_in);
} else
p = fftw_create_plan_specific(n, dir, flags,
(fftw_complex *) 0, 1, (fftw_complex *) 0, 1);
return p;
}
fftw_plan fftw_create_plan_specific(int n, fftw_direction dir, int flags,
fftw_complex *in, int istride,
fftw_complex *out, int ostride)
{
fftw_plan table;
fftw_plan p1;
/* validate parameters */
//序列长度小于零,返回
if (n <= 0)
return (fftw_plan) 0;
//屏蔽递归调用
#ifndef FFTW_ENABLE_VECTOR_RECURSE
/* TEMPORARY: disable vector recursion until it is more tested. */
flags |= FFTW_NO_VECTOR_RECURSE;
#endif
if ((dir != FFTW_FORWARD) && (dir != FFTW_BACKWARD))
return (fftw_plan) 0;
//初始化fftw_plan结构体(0)
fftw_make_empty_table(&table);
//返回最优变换方案
p1 = planner(&table, n, dir, flags, 1,
in, istride, out, ostride);
//销毁临时变量
fftw_destroy_table(&table);
//填充变换因子
if (p1)
fftw_complete_twiddle(p1->root, n);
return p1;
}
static fftw_plan planner(fftw_plan *table, int n, fftw_direction dir,
int flags, int vector_size,
fftw_complex *in, int istride,
fftw_complex *out, int ostride)
{
fftw_plan best = (fftw_plan) 0;
if (vector_size > 1)
flags |= FFTW_NO_VECTOR_RECURSE;
/* see if plan has already been computed */
//遍历已经计算过的plan链表,查找是否有相同情况情况下已经计算好的plan
best = fftw_lookup(table, n, flags, vector_size);
if (best) {
fftw_use_plan(best);
return best;
}
/* try a wise plan */
//wisdom是fftw中提高效率的一种机制,用来从内存(磁盘)里加载或者存储计算好的方案
best = planner_wisdom(table, n, dir, flags, vector_size,
in, istride, out, ostride);
if (!best) {
/* No wisdom. Plan normally. */
best = planner_normal(table, n, dir, flags,
vector_size,
in, istride, out, ostride);
}
if (best) {
//插入table中
fftw_insert(table, best);
/* remember the wisdom */
//写入wisdom
fftw_wisdom_add(n, flags, dir, FFTW_WISDOM, istride, ostride,
best->wisdom_type,
best->wisdom_signature,
best->recurse_kind);
}
return best;
}