C 写入超过2.5GB后,FPUT的性能下降。为什么?

C 写入超过2.5GB后,FPUT的性能下降。为什么?,c,windows,file-io,64-bit,large-files,C,Windows,File Io,64 Bit,Large Files,目前我正在开发一个小程序,可以读取大文件并对其进行排序。经过一些基准测试,我偶然发现了一个奇怪的性能问题。当输入文件变大时,输出文件的写入时间比实际排序时间长。因此,我深入研究了代码,最终意识到fputs函数可能是问题所在。所以我写了这个小基准测试程序 #include "stdio.h" #include "ctime" int main() { int i; const int linecount = 50000000; //Test Line with 184 b

目前我正在开发一个小程序,可以读取大文件并对其进行排序。经过一些基准测试,我偶然发现了一个奇怪的性能问题。当输入文件变大时,输出文件的写入时间比实际排序时间长。因此,我深入研究了代码,最终意识到fputs函数可能是问题所在。所以我写了这个小基准测试程序

#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);

}
#包括“stdio.h”
#包括“ctime”
int main()
{
int i;
const int linecount=50000000;
//带184字节的测试行
const char*dummyline=“这是一条很长的测试行,只是为了表明写入程序在写入了一定数量的数据后速度变慢。hkgjhkdsfjhgk jhksjdhfhk skdjhkfhk jshdkfjhksjdhf\r\n”;
时钟启动=时钟();
时钟最后一次=开始;
文件*fp1=fopen(“D:\\largeTestFile.txt”,“w”);

对于(i=0;i所有这一切的主要原因是Windows磁盘缓存。然后,您的程序为其吃掉所有RAM,然后开始交换,因此速度变慢。要解决这些问题,您需要:

1) 使用
c
标志在提交模式下打开文件:

FILE* fp1 = fopen("D:\\largeTestFile.txt", "wc");
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();
}

通过这种方式,您将使用合理数量的磁盘缓存。速度基本上会受到硬盘速度的限制。

您要写入的文件系统是什么?以及运行此代码的盒子中有多少内存?正如我在上面添加的,文件系统是NTFS。但是如果该代码在o上有相同的问题,我会非常感兴趣其他文件系统/OS。在运行测试之前是否对磁盘进行了碎片整理?顺便问一下:windows上是否存在类似/dev/null的问题?是的,碎片不应该是瓶颈。听起来很合理。我也怀疑有类似的问题。但我试过你的解决方案,这会使性能更差。现在,windows的性能与以前一样前1400万行。性能并不差,它受到硬盘速度的限制。在原始源代码中,您的数据从未实际写入文件(因此最后一次写入将花费相当长的时间)。您的“前1400万行”由于使用了交换,所以速度也受到硬盘驱动器的限制。好吧,我明白你的意思。但事实是,在我包含fflush之前花了100秒,现在花了156秒。所以添加更多RAM会有所帮助,因为缓存可能会变大?或者缓存限制在2G字节?现在,我只能假设,但我认为,这是因为Windows写关闭文件后,从缓存到后台文件的数据。如果在关闭文件句柄之前插入
fflush(fp1);
,则在这两种情况下都将获得相同的时间。同时,请确保关闭所有防病毒软件。