planner_wisdom(),fftw_wisdom_lookup(),fftw_measure_runtime(),init_test_array()函数代码分析

el/2024/4/19 23:06:57

代码分析以fftw2.15为例,原代码在fftw/planner.c中

planner_wisdom()函数是fftw为了运行效率提出的wisdom机制,主要思想是通过查找之前相似数据(结构、大小等相似)傅里✌变换时已经计算好的plan来节省时间。

static fftw_plan planner_wisdom(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;fftw_plan_node *node;int have_wisdom;enum fftw_node_type wisdom_type;int wisdom_signature;fftw_recurse_kind wisdom_recurse_kind;/* see if we remember any wisdom for this case */have_wisdom = fftw_wisdom_lookup(n, flags, dir, FFTW_WISDOM,istride, ostride,&wisdom_type, &wisdom_signature,&wisdom_recurse_kind, 0);//如果没有相关配置方案if (!have_wisdom)return best;//FFTW_NOTW和FFTW_TWIDDLE模式下的方案生成if (wisdom_type == FFTW_NOTW) {FOR_ALL_CODELETS(p) {if (p->dir == dir && p->type == wisdom_type) {/* see if wisdom applies */if (wisdom_signature == p->signature &&p->size == n) {//创建对应方案的节点node = fftw_make_node_notw(n, p);//创建执行方案best = fftw_make_plan(n, dir, node, flags,p->type, p->signature,FFTW_NORMAL_RECURSE,vector_size);fftw_use_plan(best);run_plan_hooks(best);return best;}}}}if (wisdom_type == FFTW_TWIDDLE) {FOR_ALL_CODELETS(p) {if (p->dir == dir && p->type == wisdom_type) {/* see if wisdom applies */if (wisdom_signature == p->signature &&p->size > 1 &&(n % p->size) == 0) {fftw_plan r = planner(table, n / p->size, dir, flags | FFTW_NO_VECTOR_RECURSE,wisdom_recurse_kind ==FFTW_VECTOR_RECURSE ?p->size : vector_size,in, istride, out, ostride);node = fftw_make_node_twiddle(n, p,r->root, flags);best = fftw_make_plan(n, dir, node, flags,p->type, p->signature,wisdom_recurse_kind, vector_size);fftw_use_plan(best);run_plan_hooks(best);fftw_destroy_plan_internal(r);return best;}}}}/* * BUG (or: TODO)  Can we have generic wisdom? This is probably* an academic question*/return best;
}
int fftw_wisdom_lookup(int n, int flags, fftw_direction dir,enum fftw_wisdom_category category,int istride, int ostride,enum fftw_node_type *type,int *signature, fftw_recurse_kind *recurse_kind,int replacep)
{struct wisdom *p;if (!(flags & FFTW_USE_WISDOM))return 0;		/* simply ignore if wisdom is disabled */flags |= FFTW_MEASURE;	/* * always use (only) wisdom from* measurements *///遍历链表,查找是否有相应的wisdomfor (p = wisdom_list; p; p = p->next) {if (p->n == n && p->flags == flags && p->dir == dir &&p->istride == istride && p->ostride == ostride &&p->category == category) {/* found wisdom */if (replacep) {/* replace old wisdom with new */p->type = *type;p->signature = *signature;p->recurse_kind = *recurse_kind;} else {*type = p->type;*signature = p->signature;*recurse_kind = p->recurse_kind;}return 1;}}return 0;
}

 

fftw_measure_runtime()用来评估一种变换方案的执行时间。

static double fftw_measure_runtime(fftw_plan plan,fftw_complex *in, int istride,fftw_complex *out, int ostride)
{fftw_time begin, end, start;double t, tmax, tmin;int i, iter;int n;int repeat;int howmany = plan->vector_size;n = plan->n;iter = 1;/*下面是计算耗时的程序具体计算方式为:对每一个iter重复FFTW_TIME_REPEAT次,如果计算时间过短,可能不够准确,这时通过将iter扩大二倍再进行计算,当tmin大于某一阈值(FFTW_TIME_MIN)时,将此时的结果除以iter后返回*/for (;;) {tmin = 1.0E10;tmax = -1.0E10;init_test_array(in, istride, n * howmany);start = fftw_get_time();/* repeat the measurement FFTW_TIME_REPEAT times *///运行FFTW_TIME_REPEAT次for (repeat = 0; repeat < FFTW_TIME_REPEAT; ++repeat) {begin = fftw_get_time();for (i = 0; i < iter; ++i) {fftw(plan, howmany, in, istride, istride,out, ostride, ostride);}end = fftw_get_time();t = fftw_time_to_sec(fftw_time_diff(end, begin));if (t < tmin)tmin = t;if (t > tmax)tmax = t;/* do not run for too long *///超时退出t = fftw_time_to_sec(fftw_time_diff(end, start));if (t > FFTW_TIME_LIMIT)break;}//if (tmin >= FFTW_TIME_MIN)break;iter *= 2;}tmin /= (double) iter;tmax /= (double) iter;return tmin;
}

init_test_array()函数初始化测试变换数据,这里拿出来只是因为其代表了C语言初始化数组的一种经典方式。

static void init_test_array(fftw_complex *arr, int stride, int n)
{int j;//初始化测试数组全部为零for (j = 0; j < n; ++j) {c_re(arr[stride * j]) = 0.0;c_im(arr[stride * j]) = 0.0;}
}

 


http://www.ngui.cc/el/5181819.html

相关文章

fftw 源码分析概要

fftw是MIT开源的一个快速傅里叶变换库&#xff0c;用C写成。但本次对源码的分析是在2.15版本上进行的&#xff0c;原因是最新的版本为了提升效率增加了很大的复杂性。但fftw库的主要代码结构可以通过之前的版本很好的表达出来。 但在阅读fftw3.x的源码时请注意&#xff0c;里面…

深入理解CMake

深入理解CMake1&#xff1a; https://www.jianshu.com/p/9beafc25f27f 深入理解CMake2&#xff1a; https://www.jianshu.com/p/089b458ab8d5 深入理解CMake3&#xff1a; https://www.jianshu.com/p/39fc5e548310

pytorch变量、学习率设置等trick小结

最近用到需要用到Pytorch的变量、学习率调整等操作&#xff0c;特此做个小结记录&#xff1a; 如果需要在Module中定义多个变量&#xff0c;直接在init函数中定义可能对module并不可见&#xff0c;至少打印出来优化参数时是不存在的&#xff0c;这时可以使用pytorch nn.Paramet…

Linux buff/cache过高解决 及 numpy创建大矩阵时报 MemoryError

Linux buff/cache过高解决&#xff1a; https://blog.csdn.net/sweetfather/article/details/82902140 如果遇到permission denied,请使用sudo numpy.zeros()创建大矩阵时可能会报MemeoryError&#xff0c;除了上面的释放buff外&#xff0c;还可以使用numpy的open_memmap函数…

Java解析HL7消息进阶(解析自定义HL7消息)

上一篇文章博主笼统的讲了HL7解析&#xff0c;以及解析完成的Message结构&#xff0c;详情移步&#x1f449;&#xff08;Java通过HAPI解析HL7消息&#xff09;&#xff0c;下面博主就来讲讲通过HL7如何解析自定义消息 HL7&#xff08;详情&#xff09; Health Level Seven组…

找XShell替代品,用Tabby

找XShell替代品&#xff1f;不满意FinalShell&#xff1f;我推荐这款开源工具&#x1f970; 现目前的的远程终端工具有很多&#xff0c;功能齐全好用的收费&#xff0c;免费的功能外观又不怎么满意。XShell收费而且感觉用起来也一般&#xff0c;putty免费但很不方便&#xff0c…

windows 中搭建Gogs局域git仓库

windows 中搭建Gogs局域git仓库 前言 SVN我所欲也&#xff0c;Git我所欲也~ 但是最后&#xff0c;我选择了Git&#xff0c;不为别的&#xff0c;只是好用。 Git好用&#xff0c;可是服务器搭建很麻烦&#xff0c;GitHub、GitLab、码云….. 后来我想起了我以前公司搭建的局…

关于autoprefixer 编译丢失样式 处理

/* autoprefixer: off */-webkit-box-orient: vertical; /* autoprefixer: on */ 参考&#xff1a; https://github.com/postcss/autoprefixer/issues/776

H5移动端 IOS输入法遮挡input解决思路

思路 input 输入框置于页面底部&#xff0c;用absolute绝对定位于父级底部&#xff0c;在被唤起输入框时&#xff0c;会被IOS输入法自带的toolbar遮挡住input。 So&#xff0c;我的思路就是&#xff1a;点击input框后&#xff0c;延时出现&#xff0c;等IOS输入法唤起后&#…

Chocolatey 安装与命令

Chocolatey是一款专为Windows系统开发的、基于NuGet的包管理器工具&#xff0c;类似于Node.js的npm&#xff0c;MacOS的brew&#xff0c;Ubuntu的apt-get&#xff0c;它简称为choco。Chocolatey的设计目标是成为一个去中心化的框架&#xff0c;便于开发者按需快速安装应用程序和…