C程序優化 - I/O篇(轉)

C程序優化 - I/O篇

liyuming1978(原作)

  如果有文件讀寫的話,那麼對文件的訪問將是影響程序運行速度的一大因素。提高文件訪問速度的主要辦法有兩個:一是採用內存映射文件,二是使用內存緩衝。下面是一組測試數據(見《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,buffer,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.處理的文件很大,但是運行環境內存也很大,並且一般在運行該程序的時候不運行其他消耗內存大的程序,同時用戶對速度有特別的要求,而且對內存佔用沒有什麼要求。如果以上兩個條件不滿足的時候,建議使用內存緩衝區的辦法。

 轉自(C程序優化 - I/O篇

liyuming1978(原作)

  如果有文件讀寫的話,那麼對文件的訪問將是影響程序運行速度的一大因素。提高文件訪問速度的主要辦法有兩個:一是採用內存映射文件,二是使用內存緩衝。下面是一組測試數據(見《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,buffer,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.處理的文件很大,但是運行環境內存也很大,並且一般在運行該程序的時候不運行其他消耗內存大的程序,同時用戶對速度有特別的要求,而且對內存佔用沒有什麼要求。如果以上兩個條件不滿足的時候,建議使用內存緩衝區的辦法。

發佈了70 篇原創文章 · 獲贊 6 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章