從fread和mmap談C 讀檔案的效能

2021-12-29 22:32:40 字數 962 閱讀 4250

在進行大規模資料處理時,讀檔案很有可能成為速度瓶頸。不管你的cpu有4個核還是8個核,主頻有2g還是3g,硬碟io速度總是有個上限的。在本人最近的一次經歷中,對乙個11g的文字進行資料處理,一共耗時34.8秒,其中竟然有30.2秒用在訪問io上,佔了所有時間的87%左右。

雖然說硬碟io是有上限的,那麼c++為我們提供的各函式,是否都能讓我們達到這個上限呢?為了求得真相,我對這個11g的文字用fread函式讀取,在linux下用iostat檢查硬碟的訪問速度,發現讀的速度大約在380m/s。然後用dd指令測了一下讀文字的訪問速度,發現速度可以達到460m/s。可見單執行緒fread訪問並沒有達到硬碟的讀取上限。第一次考慮會不會是fread訪問硬碟的時候有一些固定開銷,用多執行緒可以達到流水訪問io的效果提高讀文字的效率,結果發現多執行緒也只有380m/s的讀取速率。

為什麼fread的效率達不到最大呢?查閱一些資料才知,用fread/fwrite方式訪問硬碟,使用者須向核心指定要讀多少,核心再把得到的內容從核心緩衝池拷向使用者空間;寫也須要有乙個大致如此的過程。這樣在訪問io的時候就多經歷了這麼乙個核心的buffer,造成速度的限制。乙個解決的辦法是mmap。mmap就是通過把檔案的某一塊內容直接對映到使用者空間上,使用者可以直接向核心緩衝池讀寫這一塊內容,這樣一來就少了核心與使用者空間的來回拷貝所以通常更快。

為了從資料說明這個問題,我引用一位網友的結論,希望對大家有所啟發。

方法/平台/時間(秒) linux gcc windows mingw windows vc2008

scanf 2.010 3.704 3.425

cin 6.380 64.003 19.208

cin取消同步 2.050 6.004 19.616

fread 0.290 0.241 0.304

read 0.290 0.398 不支援

mmap 0.250 不支援 不支援

pascal read 2.160 4.668

作者:jiang1st2010

從string類談C 深淺拷貝的區別和意義

淺拷貝和深拷貝 深淺拷貝是在c 程式設計中,對於類物件來說,其內部存在各種型別成員變數,在拷貝過程中會出現問題。淺拷貝在有指標的情況下,淺拷貝只是增加了乙個指標指向已經存在的記憶體,而深拷貝就是增加乙個指標並且申請乙個新的記憶體,使這個增加的指標指向這個新的記憶體 char ptr int coun...

ANSYS輸出的單元和節點檔案的C語言讀入

ansys中使用ewrite來輸出當前選擇的單元到檔案。他的引數為 下面是乙個簡單的用c語言讀取二維的三角網格的例子 沒有寫入單元和節點的個數,而是通過計算行數來得到的 include stdio.h include stdlib.h ansys s element output format ch...

從初始化列表和建構函式談C 的初始化機制

綜合而言,c 中類的初始化操作有四個部分組成 1.初始化列表 所有類非靜態資料成員都可以在這裡初始化,所有類靜態資料成員都不能在這裡初始化2.建構函式體 對於類非靜態資料成員 const型成員不能在這裡初始化 引用型成員不能在這裡初始化 沒有預設建構函式的成員不能在這裡初始化 對於類靜態資料成員 可...