2013-02-20 48 views
0

我有一個win32 I/O性能問題: 我試圖使用OpenFile/WriteFile實現一個體面的寫入速度。 使用資源監控器(它設有窗戶)我測量了下面這段代碼的寫入速度,我發現它在寫入2MB /秒......win32 I/O性能問題

HANDLE hFile = INVALID_HANDLE_VALUE; 
hFile = CreateFile(
    L"test", 
    (GENERIC_READ | GENERIC_WRITE), 
    FILE_SHARE_READ, 
    NULL, 
    OPEN_ALWAYS, 
    (FILE_ATTRIBUTE_NORMAL | 
    FILE_FLAG_WRITE_THROUGH | 
    FILE_FLAG_NO_BUFFERING), 
    NULL); 
if (hFile != INVALID_HANDLE_VALUE) 
{ 
    //OK 
    unsigned long bytesWritten = 0; 
    unsigned long* Buffer = (unsigned long*)malloc(4096*sizeof(unsigned long)); 
    ZeroMemory(Buffer, 4096); //thanks to 'bash.d' 
    while (true) 
    { 
     /*the infinite loop is intentional 
      because I wanted to see if the writing speed of 2MB/sec 
      was right */ 
     WriteFile(hFile, 
      Buffer, 
      4096, 
      &bytesWritten, 
      NULL); 
     if (bytesWritten <= 0) 
     { 
      break; 
     } 
    } 
} 

我試着用以下的和它的相同...

hFile = CreateFile(
    L"test", 
    (GENERIC_READ | GENERIC_WRITE), 
    FILE_SHARE_READ, 
    NULL, 
    OPEN_ALWAYS, 
    (FILE_ATTRIBUTE_NORMAL); 

我在做什麼錯(關於寫入速度)?以及如何提高寫入速度? 謝謝你,對不起我的英語

編輯: 我在寫一個本地磁盤

+0

你在做什麼錯?爲了提高寫入速度,您可以嘗試製作比4 KiB更大的緩衝區,但這最終取決於操作系統。 – m0skit0 2013-02-20 10:54:39

+1

微型4k緩衝區確定,但2MB/s對於本地磁盤仍然很慢。當然,如果磁盤在緩慢/擁塞的網絡上... – 2013-02-20 10:56:58

+1

..或者SD卡.. – 2013-02-20 10:58:38

回答

0

這是非常有趣的,和類似的問題,我有,並能重現上與Windows Server 2個不同的服務器2003 SP2 64位(單個硬盤,不是RAID)。簡單地做一個36字節的WriteFile(),然後在一個循環中產生99964字節會產生類似的行爲(我猜測它和單次寫入和其他一些Windows版本是一樣的;這正是我碰巧使用的) 。 CPU使用率開始非常低,然後逐漸增加 - 在一臺服務器上,測試的CPU使用率約爲175GB左右(約95%爲內核時間; 60%爲我的程序,40%爲「系統」 )。

您也可以嘗試使用異步IO來獲得測試性能。這是用FILE_FLAG_OVERLAPPED打開文件並使用WriteFile的LPOVERLAPPED參數。使用FILE_FLAG_NO_BUFFERING可能會或者不會獲得更好的性能。你將不得不測試看看。

FILE_FLAG_NO_BUFFERING通常會爲您提供更一致的速度和更好的流式處理行爲,並且避免使用可能不再需要的數據污染磁盤緩存,但整體速度不一定更快。

您還應該測試以查看每個IO塊的最佳大小。根據我的經驗每次複製4k文件和每次複製1Mb文件有巨大的性能差異。

在我過去的測試中(幾年前),我發現低於64kB的塊大小由開銷占主導地位,並且總體吞吐量繼續提高,塊大小高達約512KB。如果今天的驅動器需要使用大於1MB的塊大小以獲得最大的吞吐量,我不會感到驚訝。

你目前使用的數字看起來是合理的,但可能不是最佳的。另外,我相當確定FILE_FLAG_WRITE_THROUGH可以防止使用磁盤緩存,因此會花費您一定的性能。

這將是值得的嘗試下面的事情...

1)在設備管理器中啓用 「磁盤政策」 FILE_FLAG_SEQUENTIAL_SCAN標誌

2) 「啓用高級性能」

3 )將磁盤塊大小從64 KB改爲4096 ...

4)嘗試FILE_FLAG_NO_BUFFERING

+1

異步I/O可能會使事情變得更慢與WRITE_THROUGH/NO_BUFFERING - 異步將有所幫助,如果你允許操作系統緩衝數據,這意味着更多(緩衝)寫入可以完成在之前的那些致力於媒體之前,我也很好奇爲什麼SEQUENTIAL_SCAN w應該幫助寫作表現? – 2013-02-20 14:41:13

+0

@SteveTownsend http://support.microsoft.com/kb/98756 – Saqlain 2013-02-22 07:02:30

+0

該文章沒有提到任何地方寫,這個標誌影響讀取性能 – 2013-02-25 14:25:09