我遇到win32 I / O性能问题: 我正在尝试使用OpenFile / WriteFile获得不错的写入速度。 使用资源监视器(它附带Windows)我测量了下面一段代码的写入速度,我发现它的写入速度是2MB /秒......
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 :(得分:0)
这非常有趣,类似于我遇到的问题,并且可以在Windows Server 2003 SP2 64位(单个硬盘驱动器,而不是RAID)的2个不同服务器上重现。简单地在循环中执行36字节的WriteFile()然后在循环中生成99964字节会产生类似的行为(我猜测它与单个写入以及Windows的其他一些版本相同;这正是我碰巧使用的) 。 CPU使用率开始非常低,然后逐渐增加 - 在一台服务器上,测试大约为50%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 :(得分:0)
FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH
消费级驱动器(甚至5400RPM)应能够写入~130MB /秒(单主轴,无突袭)。不应该同时发生其他IO(没有头部移动)。
有关示例,请参阅https://github.com/rusanu/writing-a-binary-file-in-c-very-fast。