文章目录
耗时分析:
在windows上进行耗时分析
1. 一个线程读取数据并fft
条件
读取,并fft。
对一个wav文件的处理过程包括:
- 读取头文件,
- 读取数据部分得到3个数组
- 把得到的3个数组分别fft
结果
对步骤1-3执行的时间和1-3总时间统计如下
一个文件的处理一共花费4238ms,主要花费在读取文件数据部分上(3522ms)
2. 一个线程不断读取并fft并保存
条件
不断读取,并不断fft,并不断保存。
如果所有逻辑用一个线程完成如下逻辑:
- 从文件名获取fft后的数组(即上面的3个步骤)
- 将数组保存
(同时,使用另一个线程不断寻找新的wav文件。)
结果
费时情况:
也就是说,第一步(读取并fft)耗时4464ms,第二步(保存)耗时119ms,一共4584ms
3. 用三个线程分别读取、fft、保存
3个线程分别完成:读取(3522ms),fft(713ms),保存(119ms)。
(同时,使用另一个线程不断寻找新的wav文件。)
没有做实验,但是花费时间由慢的线程决定,所以理论上费时3522ms
4. 一点疑问
在windlws读取一个wav文件需要3.5s,但是我以前在kuiper测试的时候,处理一个wav文件都只要1.1s。
读取wav文件命名时kuiper中sources的一个步骤,不知道为什么kuiper这么快?
难道是linux系统的io比较快?
5. 总结
像要加快处理速度,需要改写读取wav的数据的代码。
读取wav的数据部分耗时最长,是fft的5倍,所以最好是能缩短时间。
fft耗时较长,但是应该不能改写了,因为计算量大,费时正常。
所以要想办法改写读取wav数据的代码。
,
现在读取wav的数据部分的逻辑是每次读取两字节,然后把这两个字节转换为int,也就是说一次只读取一个int,要读取468750次。
如果一次读取wav的所有数据,内存也放得下,时间也可以缩短。
修改读取文件部分代码
1. 修改方法:
更改 myreader.go,读取一次返回原始数据 [][]int32
更该 fft,原来接收[[]float64, 现在接收[]int32
更改主程序,不要再用for循环读了。
2. 修改后各部分用时:
读取wav的数据:44ms
对所有通道fft:750ms
保存:123ms。
所以现在的瓶颈是fft了。以前也有人测试过fft:
他的104万费时378ms
我又测试了104万是,费时517ms,我的52万,费时250ms(750/3),比他的略差
我用的fft算法使用的是复数,复数可能有额外开销,刚好还有一个实数版本的fft,也拿来试一下。
改写fft代码
1. 改写过程
- 编写新的myfft( []float64) []float64
- 编写Myf( []int32)[]float64,这个函数会把输入扩充为2^n的float数组,然后调用myfft()
- 改写Getfft_nd(string) [][]float64,这个函数使用新的读取文件方法和新的fft方法
2. 结果
对于104万的数据
用我的fft只需要234ms
对于52万数据
用我的fft只需要91ms
3. 总结:
目前三部分理论用时为:
读取数据:44ms
对所有通道fft:91ms*3=273ms
保存:123ms。
顺便列出我的程序逻辑,方便改写为kuiper插件
涉及3个包
wav
负责读取wav,和上一版本相比,增加了两个函数,用来一次性读取wav数据
myfft
fft算法,提供Getfft_nd(string) [][]float64方法,输入地址,输出多通道的fft结果。和上一版本相比,完全不同
daomain
主程序,一个线程不断寻找wav文件,另一个线程拿到地址,依次读文件,fft,储存。
4. 后期改进空间
要改进的话可以改写主程序,用3个线程分别完成读文件,fft和储存这三个任务。
现在耗时492ms,改进后理论耗时300ms。
fft基本达到瓶颈了,不可能更快了
移植到ubuntu系统
用时582ms,费时比windows(492)稍长。
移植到Kuiper
移植过程
需要改写function和source
readWavA3.go
row2fft5.go
注意sources不能返回int32的map,只能返回float64的map
速度测试
26个文件9s,大概一个文件340ms,
性能:
前:
中:
后:
内存占用0.3g,cpu占用挺高