Re: [問題] C++寫檔案速度很慢要怎麼樣加速
※ 引述《Lepton (輕子)》之銘言:
: 我在做流體力學的時域有限差分的計算
: 需要把每一個時間點的資料存起來之後再做分析
: 但是我的計算副程式跟寫檔案花的時間幾乎是一樣長
: 我原本想說是因為硬碟讀寫速度太慢了
: 但是後來我弄了ramdisk把資料寫進去也是一樣慢
: 所以我懷疑是程式碼有問題,想問說該怎麼做改進
: 以下是我的程式碼
: 因為我存的資料是2維矩陣所以要2個迴圈然後讀資料寫到硬碟
: void writefile(float* data,string filename)
: {
: ofstream dataFile(filename.c_str());
: for (int i = 0; i < N; i++)
: {
: for (int j = 0; j < Nx; j++)
: {
: dataFile << data[j +i*Nx] << "\t";
: }
: dataFile << '\n';
: }
: dataFile.close();
: }
拋磚引玉。
首先以 io library 而言 , 正常而言 c library 比 c++ library 還快 ,
這是前人寫 acm / zerojudge 經驗得來的結果 ,
這結果是否有因實務上 compiler 更新而有所變更,我不再確定,
有興趣可自己再驗證。
binary 寫入永遠是第一優先,速度肯定比較快。
我提的 string buffer 概念實作起來初步像這樣 (純 C 示例)
#define BUF_SIZE 20000
const char * fname = "rst.txt";
void writef(const float * pNum , const size_t nX , const size_t nY)
{
char szBuf[BUF_SIZE] ;
char * pBeg = (char*)szBuf;
size_t i, j, nChars;
FILE * fp = NULL;
nChars = 0;
for(i = 0 ; i < nX ; ++i) {
for(j=0; j < nY ; ++j) {
nChars = sprintf(pBeg, "%f\t", pNum[i*nY+j]);
pBeg+=nChars;
}
*pBeg++ = '\n';
}
*pBeg = '\0';
fp = fopen(fname, "w");
fputs(fp, szBuf);
fclose(fp);
}
掌握幾個要點
[1] 避開檔案上的操作
cache speed >> memory speed >> disk speed(io operator) ,
所以盡可能將檔案操作的次數壓到最低去。
[2] 效能上和一開始的 "可能" 沒太大改善?
事實上這方法要在極大量的時候才看得出效果出來,
上百 K 時效能應看得出來。
[3] 注意這份只是 present code
一個重要的防呆我沒做,便是假設一開始的 szBuf 會容納所有輸出,
但這個在檔案真的大的時候基本上是不可能會成立的,所以必須要做一些修改,
重點的虛碼大概如下 (我沒實際跑過,可能會有 bug )
#define BUF_SIZE 2000 // szBuf 大小
#define WRI_SIZE 1500 // szBuf 存到 WRI_SIZE 時就先寫入,避開 OV
int nChars = 0, nLen = 0;
pBeg = (char*)szBuf;
for( i = 0 ; i < nX ; ++i) {
for( j = 0 ; j < nY ; ++j) {
nLen += nChars = sprintf(pBeg, "%f\t", pNum[i*nY+j]);
if( nLen >= WRI_SIZE) { // 寫入檔案
*pBeg = '\0';
fprintf(fp, "%s", szBuf);
pBeg = (char*)szBuf;
nLen = 0;
}
}
..... /* whatever */
}
這裡的寫入策略我不是採用一般的 "直到 OV" 時才寫入,而是設一門檻值 WRI_SIZE,
超過時就先寫到檔案去,但這樣 if 判斷又變多,會不會因分支預測指令使得速度又
拖慢,這就也沒再驗證了。
一次寫入的策略有許多種,是我的話我會想把 if 往外放一層回圈,
意思是一個 raw 才判斷一次要不要寫入 file 動作,
這些細節我想光用想的就很多種,再討論下去意義應已不大,
因整體概念都只是一個 : 先寫入 string buffer,再一次寫入檔案中。
有沒有再更快的方式,這個我不知道了,
但若您的 IO 次數確定有那麼頻繁、多次的話,可以的話考量架構上的修正?
至少目前 IO 瓶頸一直都是被確定的,要做加速實在有限。
--
就算把新鮮的肝拿回去,還是一樣寫碼到禿頭,加班到天亮,
永遠當老闆的傀儡 你是不是想這麼做?
是的話你就拿回去~ 拿啊!!
九世宅男 : 下輩子不要再讓我幹工程師了 ~
< Kuso 星爺語錄 >
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 180.177.73.182
→
08/13 23:35, , 1F
08/13 23:35, 1F
→
08/13 23:36, , 2F
08/13 23:36, 2F
→
08/13 23:43, , 3F
08/13 23:43, 3F
→
08/13 23:46, , 4F
08/13 23:46, 4F
→
08/13 23:47, , 5F
08/13 23:47, 5F
→
08/14 01:59, , 6F
08/14 01:59, 6F
→
08/14 10:42, , 7F
08/14 10:42, 7F
→
08/14 10:43, , 8F
08/14 10:43, 8F
推
08/14 17:13, , 9F
08/14 17:13, 9F
→
08/14 17:16, , 10F
08/14 17:16, 10F
→
08/14 17:16, , 11F
08/14 17:16, 11F
推
08/14 19:30, , 12F
08/14 19:30, 12F
→
08/14 19:32, , 13F
08/14 19:32, 13F
→
08/14 19:34, , 14F
08/14 19:34, 14F
→
08/14 23:07, , 15F
08/14 23:07, 15F
→
08/14 23:10, , 16F
08/14 23:10, 16F
→
08/14 23:11, , 17F
08/14 23:11, 17F
討論串 (同標題文章)
本文引述了以下文章的的內容:
完整討論串 (本文為第 2 之 2 篇):