fftw与matlab中的fft对比,【图片】我的FFT已经完爆FFTW 简单讲一下做这个学到的姿势【附源码】【c语言吧】_百度贴吧...

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼

5. Runtime Optimization

有时候GCC也不能优化出让我们满意的效率。所以需要让程序在运行时自己改写自身的代码了……即运行时优化。

顺便给自己打小广告 ->http://tieba.baidu.com/p/2311435355 这是我以前玩得很HIGH的一次 nop掉.net的溢出检查,事后发现原来编译选项里有这一项……后来我就再也不玩.net了…………………………

其实CVEDSP的这个不算是运行时优化,因为只是改了地址没改指令头。

通常情况下,a = b[xxx];,编译出来的机器码是mov [esp + n], yyy形式的,那么在执行这条指令时除了内存操作还要做次加法。我看了很不爽,于是把它改成mov [n], yyy的形式。但程序每次启动,用malloc分配的数组的内存地址都会变。解决方法是在运行函数前把n累加上数组的基地址。

为了标明对应的数组,我用FFFF/FFFE/FFEF/FFEE覆盖地址的前两个字节,反正这种重复性的代码里几乎不会出现FF、FE,不用考虑安全问题。运行时在内存中查找FFXX然后清零累加上相应的数组基地址就OK了。

要获得函数在内存中的地址可以用函数指针。

void (*FuncFFT_10_Orig)() = FFT_Static_10;

随便把FuncFFT_10_Orig转换成其他数据类型的指针就可以读机器码了。

如果是windows系统上,很容易就可以把机器码刷回去。但是linux下只能读不能写,原因是代码段加了写入保护。

man了一下找到mprotect这个函数:

#include

int mprotect(const void *addr, size_t len, int prot);

它可以改掉一块进程所拥有的内存的访问权限。int prot既是权限。

不过我觉得直接在代码段作修改不太好,于是准备malloc、memcpy出来再改。需要注意的是mprotect对输入的地址有限制:必须和内存分页大小对齐。使用memalign函数可以分配到页对齐的内存空间。

#include

void *memalign(size_t boundary, size_t size);

获得页大小:

#include

int pagesize = sysconf(_SC_PAGE_SIZE);

于是三个组合起来:

int pagesize = sysconf(_SC_PAGE_SIZE);

int pagenum = 1024 * 1024 / pagesize; //我偷了个懒假设机器码大小超不过1M

void* CodeFFT_10 = memalign(pagesize, pagenum * pagesize);

mprotect(CodeFFT_10, pagenum * pagesize, PROT_READ | PROT_WRITE | PROT_EXEC);

为了标识函数结束的位置,我在FFT_Static_10最后加了个四个nop:

__asm__ __volatile__ ("nop\nnop\nnop\nnop\n");

nop的十六进制是0x90,于是只要搜索0x90909090就可以获得函数结束前的地址……

不确定函数的结束地址,保险期间设为size + 20:

void (*FuncFFT_10_Orig)() = FFT_Static_10;

memcpy(CodeFFT_10, (void*)FuncFFT_10_Orig, size + 20);

下面是运行时优化:

506bb389dcf74891c097895963f52643.png

注意数组中的索引值不能超过65535,不然就覆盖到FFXX的标识符了。反正65536点以上的fft很少用到(我主要需要做STFT)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值