为什么我的C盘写测试比使用bash的简单文件拷贝慢得多?

前端之家收集整理的这篇文章主要介绍了为什么我的C盘写测试比使用bash的简单文件拷贝慢得多?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
使用下面的程序,我尝试测试使用std :: ofstream可以写入磁盘的速度.

当写入1 GiB文件时,我实现了大约300 MiB / s.

但是,使用cp命令的简单文件复制速度至少是两倍.

我的程序是否达到硬件限制,还是可以加快速度?

  1. #include <chrono>
  2. #include <iostream>
  3. #include <fstream>
  4.  
  5. char payload[1000 * 1000]; // 1 MB
  6.  
  7. void test(int MB)
  8. {
  9. // Configure buffer
  10. char buffer[32 * 1000];
  11. std::ofstream of("test.file");
  12. of.rdbuf()->pubsetbuf(buffer,sizeof(buffer));
  13.  
  14. auto start_time = std::chrono::steady_clock::now();
  15.  
  16. // Write a total of 1 GB
  17. for (auto i = 0; i != MB; ++i)
  18. {
  19. of.write(payload,sizeof(payload));
  20. }
  21.  
  22. double elapsed_ns = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now() - start_time).count();
  23. double megabytes_per_ns = 1e3 / elapsed_ns;
  24. double megabytes_per_s = 1e9 * megabytes_per_ns;
  25. std::cout << "Payload=" << MB << "MB Speed=" << megabytes_per_s << "MB/s" << std::endl;
  26. }
  27.  
  28. int main()
  29. {
  30. for (auto i = 1; i <= 10; ++i)
  31. {
  32. test(i * 100);
  33. }
  34. }

输出

  1. Payload=100MB Speed=3792.06MB/s
  2. Payload=200MB Speed=1790.41MB/s
  3. Payload=300MB Speed=1204.66MB/s
  4. Payload=400MB Speed=910.37MB/s
  5. Payload=500MB Speed=722.704MB/s
  6. Payload=600MB Speed=579.914MB/s
  7. Payload=700MB Speed=499.281MB/s
  8. Payload=800MB Speed=462.131MB/s
  9. Payload=900MB Speed=411.414MB/s
  10. Payload=1000MB Speed=364.613MB/s

更新

我从std :: ofstream更改为fwrite:

  1. #include <chrono>
  2. #include <cstdio>
  3. #include <iostream>
  4.  
  5. char payload[1024 * 1024]; // 1 MiB
  6.  
  7. void test(int number_of_megabytes)
  8. {
  9. FILE* file = fopen("test.file","w");
  10.  
  11. auto start_time = std::chrono::steady_clock::now();
  12.  
  13. // Write a total of 1 GB
  14. for (auto i = 0; i != number_of_megabytes; ++i)
  15. {
  16. fwrite(payload,1,sizeof(payload),file );
  17. }
  18. fclose(file); // TODO: RAII
  19.  
  20. double elapsed_ns = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now() - start_time).count();
  21. double megabytes_per_ns = 1e3 / elapsed_ns;
  22. double megabytes_per_s = 1e9 * megabytes_per_ns;
  23. std::cout << "Size=" << number_of_megabytes << "MiB Duration=" << long(0.5 + 100 * elapsed_ns/1e9)/100.0 << "s Speed=" << megabytes_per_s << "MiB/s" << std::endl;
  24. }
  25.  
  26. int main()
  27. {
  28. test(256);
  29. test(512);
  30. test(1024);
  31. test(1024);
  32. }

其中将1Gb文件的速度提高到668MiB / s:

  1. Size=256MiB Duration=0.4s Speed=2524.66MiB/s
  2. Size=512MiB Duration=0.79s Speed=1262.41MiB/s
  3. Size=1024MiB Duration=1.5s Speed=664.521MiB/s
  4. Size=1024MiB Duration=1.5s Speed=668.85MiB/s

哪个跟dd一样快:

  1. time dd if=/dev/zero of=test.file bs=1024 count=0 seek=1048576
  2.  
  3. real 0m1.539s
  4. user 0m0.001s
  5. sys 0m0.344s
首先,您不是真正测量磁盘写入速度,而是(部分)将数据写入操作系统磁盘缓存的速度.要真正测量磁盘写入速度,在计算时间之前,应将数据刷新到磁盘.没有刷新可能会有所不同取决于文件大小和可用的内存.

计算中似乎也有错误.你没有使用MB的值.

还要确保缓冲区大小是2的幂,或至少是磁盘页大小(4096字节)的倍数:char buffer [32 * 1024] ;.你也可以这样做为有效载荷. (看起来您在添加计算的编辑中将其从1024更改为1000).

不要使用流将数据写入(二进制)缓冲区到磁盘,而是使用FILE *,fopen(),fwrite(),fclose()直接写入文件.参见this answer的一个例子和一些时间.

要复制文件:以只读方式打开源文件,如果可能的话,只进行转发模式,并使用fread(),fwrite():

  1. while fread() from source to buffer
  2. fwrite() buffer to destination file

这应该给你一个与操作系统文件副本的速度相当的速度(你可能想要测试一些不同的缓冲区大小).

使用内存映射可能会稍微加快一点:

  1. open src,create memory mapping over the file
  2. open/create dest,set file size to size of src,create memory mapping over the file
  3. memcpy() src to dest

对于大文件,应使用较小的映射视图.

猜你在找的Bash相关文章