2016-02-18 140 views
-1

我正在開發一個程序,其中包含多個線程來管理來自多個攝像頭的數據流。我必須在SSD磁盤上寫入每個原始圖像。我正在使用fwrite將圖像置於二進制文件中。例如:限制fwrite操作的CPU使用率

FILE* output; 
output = fopen(fileName, "wb"); 
fwrite(imageData, imageSize, 1, output); 
fclose(output); 

該過程似乎運行得足夠快,以保存具有給定攝像機吞吐量的所有圖像。問題在於保存過程耗費CPU資源,並且由於保存線程的CPU使用情況,啓用保存進程時,我開始出現同步問題。

有什麼辦法可以減少fwrite操作的CPU負載嗎?喜歡玩緩衝,更好的DMA設置,...?

謝謝!

MIX

- 更新1

忘了多線程的軟件,這裏是一個簡單的文件刻錄軟件:

#include <stdio.h> 
#include <stdlib.h> 

const unsigned int TOT_DATA = 1280*2*960; 

int main(int argc, char* argv[]) 
{ 
    if(argc != 2) 
    { 
    printf("Usage:\n"); 
    printf(" %s totWrite\n\n", argv[0]); 
    return -1; 
    } 

    char* imageData; 
    FILE* output; 
    char fileName[256]; 
    unsigned int totWrite; 

    totWrite = atoi(argv[1]); 
    imageData = new char[TOT_DATA]; 

    printf("Write imageData[%u] on file %u times.\n", TOT_DATA, totWrite); 
    for(unsigned int i = 0; i < totWrite; i++) 
    { 
    sprintf(fileName, "image_%06u.raw", i); 
    output = fopen(fileName, "wb"); 
    fwrite(imageData, TOT_DATA, 1, output); 
    fclose(output); 
    } 
    printf("DONE!\n"); 

    delete [] imageData; 

    return 0; 
} 

char緩衝區將被創建,它會寫上文件totWrite次。由於每個循環寫入新文件,因此不會覆蓋。 (當然,必須刪除以前運行的文件...)

運行top(我在Linux上)程序運行時我看到大約50%的CPU(這意味着50%的使用4個核心之一)。我認爲fwrite是CPU使用率的瓶頸,因爲它是循環中的「較慢」操作,所以當更新其狀態時,「更可能」運行該操作。即使「更可能」,如果TOT_DATA將增加,例如100次。

關於什麼可以減少此類程序中CPU使用率的進一步考慮?

+3

你確定fwrite消耗很多CPU嗎?它只應該被阻擋,因爲硬盤速度不是很快。不過,您可以嘗試操作系統級別的功能,如打開/寫入或CreateFile/WriteFile。 –

+4

請勿在每次寫入時打開/關閉文件。 – Mat

+0

@Mat不確定這是一個問題 - 它可能是'fwrite'是所有應該寫入文件的寫入。 – skyking

回答

0

如果您考慮使用DMA設置進行遊戲,那麼您已經超出了標準C庫的範圍。它遠不是便攜式的 - 然後你沒有使用便攜式功能的好處。你可能應該使用的第一步(在你確認CPU是瓶頸之後)是使用較低級別的函數,例如open/write(或者你的操作系統稱之爲)。

基本上,fwrite可能發生的情況是,在將數據寫入光盤之前,程序首先將數據複製到內存中的另一個位置(FILE*緩衝區)。這種操作當然是CPU綁定的,如果CPU的數據傳輸速度慢於數據傳輸到SSD的速度,可能會導致無法正常使用CPU功耗的情況。

還應該指出,使用多線程有缺點。首先,如果它不是SSD,多個線程寫入磁盤可能會導致冗餘磁頭移動,這並不壞,但即使SSD可能會受到一定程度的影響,因爲您可能會分割數據的佈局。

加載整個文件時也有問題,就像您在示例中似乎要做的那樣,特別是在多線程中執行時。它會消耗大量內存(這可能導致需要交換)。如果可能,您應該在數據到達時將數據寫入文件。