C程序优化之路(一)

 本文讲述在编写C程序代码的常用优化办法,分为I/O篇,内存篇,算法篇,MMX汇编篇。

一.I/O

  如果有文件读写的话,那么对文件的访问将是影响程序运行速度的一大因 素。提高文件访问速度的主要办法有两个:一是采用内存映射文件,二是使用内存缓冲。下面是一组测试数据(见《UNIX环境高级编程》3.9节),显示了用 18种不同的缓存长度,读1 468 802字节文件所得到的结果。

缓冲大小

用户CPU(秒)

系统CPU(秒)

时钟时间(秒)

循环次数(秒)

1

23.8

397.9

423.4

1 468 802

2

12.3

202.0

215.2

734 401

4

6.1

100.6

107.2

367 201

8

3.0

50.7

54.0

183 601

16

1.5

25.3

27.0

91 801

32

0.7

12.8

13.7

45 901

64

0.3

6.6

7.0

22 951

128

0.2

3.3

3.6

11 476

256

0.1

1.8

1.9

5 738

512

0.0

1.0

1.1

2 869

1 024

0.0

0.6

0.6

1 435

2 048

0.0

0.4

0.4

718

4 096

0.0

0.4

0.4

359

8 192

0.0

0.3

0.3

180

16 384

0.0

0.3

0.3

90

32 768

0.0

0.3

0.3

45

65 536

0.0

0.3

0.3

23

131 072

0.0

0.3

0.3

12

可见,一般的当内存缓冲区大小为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.处理的文件很大,但是运行环境内存也很大,并且一般在运行该程序的时候不运行其他消耗内 存大的程序,同时用户对速度有特别的要求,而且对内存占用没有什么要求。如果以上两个条件不满足的时候,建议使用内存缓冲区的办法。

发布了23 篇原创文章 · 获赞 3 · 访问量 11万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章