代码分析以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;}
}

planner_wisdom(),fftw_wisdom_lookup(),fftw_measure_runtime(),init_test_array()函数代码分析相关推荐

  1. caffe中loss函数代码分析--caffe学习(16)

    接上篇:caffe中样本的label一定要从序号0开始标注吗?–caffe学习(15) A: 1:数学上来说,损失函数loss值和label从0开始还是从1或者100开始是没有直接联系的,以欧式距离损 ...

  2. AC_AttitudeControl_Heli.cpp的AC_AttitudeControl_Heli::rate_target_to_motor_yaw函数代码分析

    代码基于ardupilot3.4.2RC2,仅分析ArduCopter(多旋翼.直升机)构型中代码逻辑.使用关系,其他构型(飞机.云台.车)后续考虑分析. float AC_AttitudeContr ...

  3. AC_AttitudeControl_Heli.cpp的AC_PosControl::set_dt函数代码分析

    代码基于ardupilot3.4.2RC2,仅分析ArduCopter(多旋翼.直升机)构型中代码逻辑.使用关系,其他构型(飞机.云台.车)后续考虑分析. void AC_PosControl::se ...

  4. AC_AttitudeControl_Heli.cpp的void AC_AttitudeControl_Heli::rate_bf_to_motor_roll_pitch函数代码分析

    代码基于ardupilot3.4.2RC2,仅分析ArduCopter(多旋翼.直升机)构型中代码逻辑.使用关系,其他构型(飞机.云台.车)后续考虑分析. void AC_AttitudeContro ...

  5. AC_AttitudeControl_Heli.cpp的AC_AttitudeControl_Heli::passthrough_bf_roll_pitch_rate_yaw函数代码分析

    代码基于ardupilot3.4.2RC2,仅分析ArduCopter(多旋翼.直升机)构型中代码逻辑.使用关系,其他构型(飞机.云台.车)后续考虑分析. 函数作用:传统直升机(单旋翼带尾桨)带平衡杠 ...

  6. WinCE 开始菜单StartMenu_Create()函数代码分析

    //================================================================================================== ...

  7. linux ip rcv,Linux网络层 ip_rcv()函数代码分析(__pskb_pull_tail)

    int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt) //几个结构sk_buff套接字缓存,n ...

  8. Linux内核分析2:一个简单的时间片轮转多道程序内核代码分析

    Lab2:一个简单的时间片轮转多道程序内核代码 席金玉   <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-100002900 ...

  9. 【FFmpeg编程进阶】(15)FLV 编码器Codec初始化 ff_mpv_encode_init() 代码分析 -- 待更新

    [FFmpeg编程进阶](15)FLV 编码器Codec初始化 ff_mpv_encode_init 代码分析 一.ff_mpv_encode_init() 在前面分析<[FFmpeg编程进阶] ...

最新文章

  1. c语言int64编译时错误,错误:编译C程序时未在此作用域中声明uint64_t
  2. 软件工程 项目管理的目标和细节
  3. 在视图控制器之间传递数据
  4. 纯CSS画的基本图形(矩形、圆形、三角形、多边形、爱心、八卦等),里面很多涉及到CSS3的一些属性。
  5. NameNode和SecondaryNameNode工作机制
  6. oracle 拷贝文件到asm,Oracle 从ASM复制文件到文件系统
  7. 4、mybatis通过配置类Configuration 实现初始化
  8. SQL Server游标使用快速上手
  9. 10_android打包的过程
  10. c语言编程简单教学,C语言入门教程-最简单的C程序
  11. 高淇java300适合_高淇java300集JAVA面向对象的进阶作业
  12. ABAP 中的搜索帮助
  13. 百度SEO站群WordPress企业主题:企业一号 V 1.2.2
  14. 5G协议 基本架构 专有名词简称和缩写
  15. Parity(奇偶校验)和ECC(错误检查和纠正)
  16. wps教鞭功能_三个PPT2010新增实用功能
  17. 手机怎么模拟125k卡_【个性nubia之路】无卡开门禁:教你用手机NFC模拟门禁卡
  18. java 字符串很长_String:java:常量字符串过长
  19. altium芯片原理图导入cadence库
  20. Eclipse资源管理IResource,IWorkspace,IProject, IFolder,IPath

热门文章

  1. 字体大宝库:20款充满艺术感的高质量英文字体
  2. modbus的寄存器的地址
  3. TTL电平、CMOS电平、RS232电平的介绍
  4. 如何升级为Windows10系统
  5. Linux学习(一)用户管理
  6. 使用Arduino开发ESP32(13):SD卡的使用
  7. 关于Blog搬家这件事
  8. 跨域预训练语言模型(XLM)
  9. 打开svn时候出现R6034
  10. python3通过CookieJar与urllib模拟登陆人人网