您的位置:首页 > 职场人生

C程序优化之路(一)

2010-05-27 11:40 239 查看
本文讲述在编写C程序代码的常用优化办法,分为I/O篇,内存篇,算法篇,MMX汇编篇。
一.I/O篇
  如果有文件读写的话,那么对文件的访问将是影响程序运行速度的一大因素。提高文件访问速度的主要办法有两个:一是采用内存映射文件,二是使用内存缓冲。下面是一组测试数据(见《UNIX环境高级编程》3.9节),显示了用18种不同的缓存长度,读1 468 802字节文件所得到的结果。
[align=center]缓冲大小[/align][align=center]用户CPU(秒)[/align][align=center]系统CPU(秒)[/align][align=center]时钟时间(秒)[/align]循环次数(秒)
[align=center]1[/align][align=center]23.8[/align][align=center]397.9[/align][align=center]423.4[/align][align=center]1 468 802[/align]
[align=center]2[/align][align=center]12.3[/align][align=center]202.0[/align][align=center]215.2[/align][align=center]734 401[/align]
[align=center]4[/align][align=center]6.1[/align][align=center]100.6[/align][align=center]107.2[/align][align=center]367 201[/align]
[align=center]8[/align][align=center]3.0[/align][align=center]50.7[/align][align=center]54.0[/align][align=center]183 601[/align]
[align=center]16[/align][align=center]1.5[/align][align=center]25.3[/align][align=center]27.0[/align][align=center]91 801[/align]
[align=center]32[/align][align=center]0.7[/align][align=center]12.8[/align][align=center]13.7[/align][align=center]45 901[/align]
[align=center]64[/align][align=center]0.3[/align][align=center]6.6[/align][align=center]7.0[/align][align=center]22 951[/align]
[align=center]128[/align][align=center]0.2[/align][align=center]3.3[/align][align=center]3.6[/align][align=center]11 476[/align]
[align=center]256[/align][align=center]0.1[/align][align=center]1.8[/align][align=center]1.9[/align][align=center]5 738[/align]
[align=center]512[/align][align=center]0.0[/align][align=center]1.0[/align][align=center]1.1[/align][align=center]2 869[/align]
[align=center]1 024[/align][align=center]0.0[/align][align=center]0.6[/align][align=center]0.6[/align][align=center]1 435[/align]
[align=center]2 048[/align][align=center]0.0[/align][align=center]0.4[/align][align=center]0.4[/align][align=center]718[/align]
[align=center]4 096[/align][align=center]0.0[/align][align=center]0.4[/align][align=center]0.4[/align][align=center]359[/align]
[align=center]8 192[/align][align=center]0.0[/align][align=center]0.3[/align][align=center]0.3[/align][align=center]180[/align]
[align=center]16 384[/align][align=center]0.0[/align][align=center]0.3[/align][align=center]0.3[/align][align=center]90[/align]
[align=center]32 768[/align][align=center]0.0[/align][align=center]0.3[/align][align=center]0.3[/align][align=center]45[/align]
[align=center]65 536[/align][align=center]0.0[/align][align=center]0.3[/align][align=center]0.3[/align][align=center]23[/align]
[align=center]131 072[/align][align=center]0.0[/align][align=center]0.3[/align][align=center]0.3[/align][align=center]12[/align]
可见,一般的当内存缓冲区大小为8192的时候,性能就已经是最佳的了,这也就是为什么在H.263等图像编码程序中,缓冲区大小为8192的原因(有的时候也取2048大小)。使用内存缓冲区方法的好处主要是便于移植,占用内存少,便于硬件实现等。下面是读取文件的C伪码:
int Len;
BYTE buffer[8192];
ASSERT(buffer==NULL);
If buffer is empty{
Len=read(File,ld->rdbfr,8192);
If(len==0) No data and exit;
}
  但是如果内存比较大的时候,采用内存映射文件可以达到更佳性能,并且编程实现简单。内存映射的具体使用说明见msdn October 2001中的Platform SDK
Documentation—Base Services—File Storage—File Mapping。下面是一点建议:
① 内存映射文件不能超过虚拟内存的大小,最好也不要太大,如果内存映射文件接近虚拟内存大小的时候,反而会大大降低程序的速度(其实是因为虚拟内存不足导致系统运行效率降低),这个时候,可以考虑分块映射,但是我觉得如果这样,还不如直接使用内存缓冲来得直接一些。
② 可以将两种方法统一使用,如我在编大图像文件数据处理的时候(因为是Unix工作站,内存很大GB单位)使用了内存映射文件,但是为了最佳性能,也使用了一行图像缓存,这样在读取文件中数据的时候,就保证了仅仅是顺序读写(内存映射文件中,对顺序读写有专门的优化)。
③ 在写文件的时候使用内存映射文件要有一点小技巧:应该先创建足够大的文件,然后将这个文件映射,在处理完这个文件的时候,用函数SetFilePointer和SetEndOfFile来对文件进行截尾。
④ 对内存映射文件进行操作与对内存进行操作类似(使用起来就象数组一样),那么如果有大块数据读写的时候,切记使用memcpy()函数(或者CopyMemory()函数)

  总之,如果要使用内存映射文件,必须:1.处理的文件比较的小,2.处理的文件很大,但是运行环境内存也很大,并且一般在运行该程序的时候不运行其他消耗内存大的程序,同时用户对速度有特别的要求,而且对内存占用没有什么要求。如果以上两个条件不满足的时候,建议使用内存缓冲区的办法。

转自:http://dev.gameres.com/Program/Other/OP_IO.htm
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  职场 休闲 程序优化