宋贤广 2008-04-21
song.xian-guang _at_ hotmail _dot_ com
(如需转载请注明出处,谢谢)
最近在做网卡固件开发的工作,我深切的感受到了CPU和内存速率不匹配而带来的性能低下问题。
现代通用CPU增加了多级cache和超流水线来缓解这种不匹配,从而极大的提升了性能;嵌入式CPU一样也引入了cache的概念,我所作的项目中,网卡上含有4个CPU,每个CPU有独立的一级cache,4个CPU共享二级cache。
该网卡正常的固件流程如下:
(1)负责收包的硬件部件会接收电气信号,并转化成数据放到内存上,并生成一个消息放进CPU的消息队列(硬件队列)
(2)CPU轮询消息队列,取出消息,####,得到数据包的地址和长度,发起DMA
(3)网卡上的DMA控制器负责将网卡内存中的数据包传送到主机,并适时给出中断信号
CPU执行的固件指令基本上都能在cache中找到,除了指令数据之外,CPU基本不怎么访问大量内存,系统运行飞快;但是由于项目需要,在####的地方需要加入额外动作,修改网卡内存中的数据包,这就涉及到了CPU操作内存的问题,由于每个数据包的地址和长度等都不相同,导致了cache抖动厉害,命中率极低,相当于CPU直接与内存交互了。做项目的时候,曾被告知,这个网卡是cache-sensitive的,当时以为这个这个网卡的优点,后来我意识到,所谓的cache敏感,并不是该卡的优点,而实质上是一种无奈。通常,出于各种考虑,嵌入式CPU功能单一,不具备多线程和超流水的能力,只要出现cache不命中的情况,那它就要等待,而访问物理内存的低效率势必要降低系统的整体性能。从这个意义上讲,一般的嵌入式CPU都是cache-sensitive的,这是嵌入式系统的一种硬伤了。我试验过了,一个几百字节的memset操作,就将导致网卡速率降低五六百兆!
如果你发现你的嵌入式系统性能低下,那你就要考虑一下cache优化了,我总结了几点供大家参考吧:
(1)定义变量和数据结构的时候,一定要注意cache line对齐,比如__attribute__ ((aligned(512)))就是在512字节地址上对齐
(2)常用的代码段集中存放,比如__attribute__((section(".text_core")))可将一个函数放在.text_core段中,将常用的函数集中到一个段中,有利于增加cache命中率
(3)常用的数据段集中存放
(4)少用链表多用数组,因为数组一般都是连续的
(5)尽量避免使用memcpy, memset等内存操作函数
本文意在抛砖引玉,欢迎大家补充意见。
sxg
阅读(1644) | 评论(1) | 转发(0) |