2016-03-02 55 views
3

在給定的學校摘錄中,我被要求測量處理器的運行時間。 其中,我被問及測量訪問磁盤所花費的時間,並強烈建議在文件上使用函數。成功寫入結果訪問磁盤只有一次

因此,我想出了這個簡單的「解決方案」:

/* Time measurement function for accessing the disk. 
    returns time in nano-seconds upon success, 
    and -1 upon failure. 
    */ 
double osm_disk_time(unsigned int iterations) 
{ 
    // Check for illegal input 
    iterations = (iterations == ILLEGAL_ITER_NUM) ? DEFAULT_ITER_NUM:iterations; 

    // Start measuring. 
    startTimeSuccess = gettimeofday(&timeStart, NULL); 
    for (unsigned int i = 0; i < iterations/ LOOP_FACTOR; ++i) { 
     //operation. (loop unrolling): Write a char and flush memory 

     if (fputs(LETTER_TO_WRITE, pFile) < SUCCESS || fflush(pFile) < SUCCESS) 
     { 
      return FAILURE; 
     } 

     if (fputs(LETTER_TO_WRITE, pFile) < SUCCESS || fflush(pFile) < SUCCESS) 
     { 
      return FAILURE; 
     } 

     if (fputs(LETTER_TO_WRITE, pFile) < SUCCESS || fflush(pFile) < SUCCESS) 
     { 
      return FAILURE; 
     } 
    } 
    // Stop measuring. 
    endTimeSuccess = gettimeofday(&timeEnd, NULL); 

    return returnValueChecker(startTimeSuccess, endTimeSuccess, iterations); 
} 

的問題是,我的測定時間爲顯著低於avrege。 根據我所做的一些研究,我瞭解多個「寫入」只能訪問一次磁盤,這可能是我的措施不準確的原因。 我不明白爲什麼會發生,我能做些什麼來解決這個問題。

(PS:returnValueChecker()只是檢查返回的值)。

+1

我認爲是因爲OS/Program緩衝你的寫入效率更高。 – Neijwiert

+0

在'fputs()'語句之後使用'flush()'。 –

+0

也可以使用C++ 11嗎?因爲'std :: chrono :: high_resolution_clock',可能會更精確。 – Neijwiert

回答

3

有幾個級別的緩存參與。第一個是在圖書館本身。你使用fflush來緩解它。第二個是在操作系統中,稱爲頁面緩存。還有第三個 - 磁盤驅動器本身的硬件緩存。

爲了避免緩存影響可以有幾個策略:遠遠大於可用的RAM數量

  • 使用的文件。這樣整個文件不能被緩存在RAM中。

  • 使用特殊調用來直接訪問磁盤(在OS文檔中查看它),或者像使用庫緩存一樣清空OS緩存。例如用POSIX的fsync調用。

  • 您最有可能對隨機存取時間感興趣。因此,創建一個大文件(> RAM),然後在隨機位置讀/寫。

+1

*在寫出後在隨機位置閱讀*。 (重複模式很好; SSD壓縮對延遲的幫助不應太大。)寫入可以被緩存,但只有實際存在數據時,「讀取」才能返回。要*真正*防止任何重疊,使下一個讀取位置的數據依賴於前一次讀取(即指針追逐,如你如何測試內存/ CPU緩存延遲負載使用延遲。) –

+1

隨機寫入流仍然很慢,但它們可以稍微流水。硬盤從更高的隊列深度獲得更好的吞吐量。 'fsync'是一個很好的建議,但會同步元數據*和*數據。 'fdatasync'只會同步數據。如果您試圖衡量一個磁盤尋道的延遲,這將有所幫助。 –

0

在寫入文件後,可以調用fsync(file_descriptor)。該調用會將緩衝區中的數據刷新到磁盤。 或 您可以通過O_SYNC標誌打開打開文件的調用。 這將關閉優化,即每次進行寫入調用時都會將數據刷新到磁盤。