Ace*_*ine 8 c windows 64-bit file-io large-files
目前我正在研究一个小程序,它读取大文件并对它们进行排序.经过一些基准测试后,我偶然发现了一个奇怪的性能问题.当输入文件变大时,输出文件的写入花费的时间比实际排序要长.所以我深入研究了代码并最终意识到fputs-function可能是问题所在.所以我写了这个小基准程序.
#include "stdio.h"
#include "ctime"
int main()
{
int i;
const int linecount = 50000000;
//Test Line with 184 byte
const char* dummyline = "THIS IS A LONG TEST LINE JUST TO SHOW THAT THE WRITER IS GUILTY OF GETTING SLOW AFTER A CERTAIN AMOUNT OF DATA THAT HAS BEEN WRITTEN. hkgjhkdsfjhgk jhksjdhfkjh skdjfhk jshdkfjhksjdhf\r\n";
clock_t start = clock();
clock_t last = start;
FILE* fp1 = fopen("D:\\largeTestFile.txt", "w");
for(i=0; i<linecount; i++){
fputs(dummyline, fp1);
if(i%100000==0){
printf("%i Lines written.\r", i);
if(i%1000000 == 0){
clock_t ms = clock()-last;
printf("Writting of %i Lines took %i ms\n", i, ms);
last = clock();
}
}
}
printf("%i Lines written.\n", i);
fclose(fp1);
clock_t ms = clock()-start;
printf("Writting of %i Lines took %i ms\n", i, ms);
}
Run Code Online (Sandbox Code Playgroud)
当您执行该程序时,您可以看到大约14到15 mio行后的性能明显下降,大约2.5GB的数据.写作大约需要3倍的时间.2GB的阈值表示64位问题,但我在网络上没有发现任何相关信息.我还测试了二进制和字符模式之间是否存在差异(例如"wb"和"w"),但没有.我还尝试通过寻找预期的结束并编写一个zerobyte来预分配文件大小(以避免文件碎片),但这也几乎没有效果.
我正在运行Windows 7 64位机器,但我也在Windows Server 2008 64位R1机器上进行了测试.目前我正在测试具有超过200GB可用空间的NTFS文件系统.我的系统有16GB的RAM,所以这也不应该是一个问题.测试程序仅使用大约700KB.我之前怀疑的页面错误也很低(在整个运行时期间有大约400页的错误).
我知道对于这样大的数据,fwrite() - 函数可以更好地适应任务,但目前我感兴趣的是是否有另一种解决方法以及为什么会发生这种情况.任何帮助将受到高度赞赏.
所有这一切的主要原因是Windows磁盘缓存.然后你的程序为它吃掉所有的RAM,然后开始交换,从而减慢速度.为了对抗这些,你需要:
1)使用cflag 在提交模式下打开文件:
FILE* fp1 = fopen("D:\\largeTestFile.txt", "wc");
Run Code Online (Sandbox Code Playgroud)
2)使用flush函数定期将缓冲区写入磁盘:
if(i%1000000 == 0)
{
// write content to disk
fflush(fp1);
clock_t ms = clock()-last;
printf("Writting of %i Lines took %i ms\n", i, ms);
last = clock();
}
Run Code Online (Sandbox Code Playgroud)
这样您就可以使用合理数量的磁盘缓存.速度基本上受硬盘速度的限制.
| 归档时间: |
|
| 查看次数: |
635 次 |
| 最近记录: |