Sta*_*ked 14 c++ performance fstream
使用下面的程序我尝试测试我可以用多快的速度写入磁盘std::ofstream.
在写入1 GiB文件时,我达到大约300 MiB/s.
但是,使用该cp命令的简单文件复制速度至少快两倍.
我的程序是否达到了硬件限制,还是可以更快?
#include <chrono>
#include <iostream>
#include <fstream>
char payload[1000 * 1000]; // 1 MB
void test(int MB)
{
// Configure buffer
char buffer[32 * 1000];
std::ofstream of("test.file");
of.rdbuf()->pubsetbuf(buffer, sizeof(buffer));
auto start_time = std::chrono::steady_clock::now();
// Write a total of 1 GB
for (auto i = 0; i != MB; ++i)
{
of.write(payload, sizeof(payload));
}
double elapsed_ns = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now() - start_time).count();
double megabytes_per_ns = 1e3 / elapsed_ns;
double megabytes_per_s = 1e9 * megabytes_per_ns;
std::cout << "Payload=" << MB << "MB Speed=" << megabytes_per_s << "MB/s" << std::endl;
}
int main()
{
for (auto i = 1; i <= 10; ++i)
{
test(i * 100);
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
Payload=100MB Speed=3792.06MB/s
Payload=200MB Speed=1790.41MB/s
Payload=300MB Speed=1204.66MB/s
Payload=400MB Speed=910.37MB/s
Payload=500MB Speed=722.704MB/s
Payload=600MB Speed=579.914MB/s
Payload=700MB Speed=499.281MB/s
Payload=800MB Speed=462.131MB/s
Payload=900MB Speed=411.414MB/s
Payload=1000MB Speed=364.613MB/s
Run Code Online (Sandbox Code Playgroud)
我从改std::ofstream到fwrite:
#include <chrono>
#include <cstdio>
#include <iostream>
char payload[1024 * 1024]; // 1 MiB
void test(int number_of_megabytes)
{
FILE* file = fopen("test.file", "w");
auto start_time = std::chrono::steady_clock::now();
// Write a total of 1 GB
for (auto i = 0; i != number_of_megabytes; ++i)
{
fwrite(payload, 1, sizeof(payload), file );
}
fclose(file); // TODO: RAII
double elapsed_ns = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now() - start_time).count();
double megabytes_per_ns = 1e3 / elapsed_ns;
double megabytes_per_s = 1e9 * megabytes_per_ns;
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;
}
int main()
{
test(256);
test(512);
test(1024);
test(1024);
}
Run Code Online (Sandbox Code Playgroud)
这样可以将1 GiB文件的速度提高到668MiB/s:
Size=256MiB Duration=0.4s Speed=2524.66MiB/s
Size=512MiB Duration=0.79s Speed=1262.41MiB/s
Size=1024MiB Duration=1.5s Speed=664.521MiB/s
Size=1024MiB Duration=1.5s Speed=668.85MiB/s
Run Code Online (Sandbox Code Playgroud)
这跟以下一样快dd:
time dd if=/dev/zero of=test.file bs=1024 count=0 seek=1048576
real 0m1.539s
user 0m0.001s
sys 0m0.344s
Run Code Online (Sandbox Code Playgroud)
Dan*_*_ds 15
首先,您并没有真正测量磁盘写入速度,而是(部分)将数据写入操作系统磁盘缓存的速度.要真正测量磁盘写入速度,应在计算时间之前将数据刷新到磁盘.如果没有刷新,可能会有所不同,具体取决于文件大小和可用内存.
计算中似乎也有问题.你没有使用的价值MB.
另外,还要确保缓冲区的大小是2的幂,或者至少是磁盘页面大小(4096个字节)的倍数:char buffer[32 * 1024];.你也可以这样做payload.(看起来您在添加计算的编辑中将其从1024更改为1000).
不要使用流将(二进制)数据缓冲区写入磁盘,而是使用直接写入文件FILE*, fopen(), fwrite(), fclose().请参阅此答案以获取示例和一些时间.
复制文件:以只读方式打开源文件,如果可能,以只进模式打开源文件,并使用fread(), fwrite():
while fread() from source to buffer
fwrite() buffer to destination file
Run Code Online (Sandbox Code Playgroud)
这应该可以提供与OS文件副本速度相当的速度(您可能希望测试一些不同的缓冲区大小).
这可能会使用内存映射略快:
open src, create memory mapping over the file
open/create dest, set file size to size of src, create memory mapping over the file
memcpy() src to dest
Run Code Online (Sandbox Code Playgroud)
对于大文件,应使用较小的映射视图.
| 归档时间: |
|
| 查看次数: |
1225 次 |
| 最近记录: |