2013-02-20 45 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