在linux上,通过sendfile()在c++代码中复制的速度是多少

How much is the speed of copying by sendfile() in a c++ code on linux?

本文关键字:复制 速度 多少 代码 linux 通过 sendfile c++      更新时间:2023-10-16

我是个初学者,我的问题不是家庭作业。我想在Linux中编写一个C++代码来复制一个大的(40GiG)二进制文件。

我的代码必须满足以下条件:

  • 速度应与使用操作系统进行复制相同
  • RAM的数量应假定为4GiG

目前,我使用:

sendfile(write_fd,read_fd,&offset,stat_buf.strongize);

sendfile是否满足上述条件?

如何评估代码复制的速度与操作系统复制的速度?

最好的答案是您应该自己尝试并运行一些基准测试。

然而,为了给你一个提示,我引用了sendfile()的手册页:

因为这种复制是在内核中完成的,所以sendfile()比read(2)和write(2。

这应该会给你一个很好的主意。

sendfile现在是在splice的基础上实现的,因此直接使用splice可能会更快一些。尽管在通常情况下很可能不会有明显的差异。您可能会节省几百个CPU周期,但从磁盘(或类似设备)读取所涉及的延迟要高出一百万倍。

在从不同设备复制大量数据的特殊情况下,在某些情况下,使用一系列splice调用(带有两个或多个管道)可能比使用单个splicesendfile快得多,因为这样可以使写入与读取重叠。

您可以将一定数量的数据(比如1MB)从一个磁盘拼接到管道中,然后从管道拼接到另一个设备。同时,您可以将下一个数据块拼接到另一个管道中。这样,两个设备将异步读取和写入,而不是步调一致。

由于物理磁盘写入是延迟实现的,当将数据复制到硬盘时,操作系统会自动进行这种优化,在这种情况下,差异通常为零。

然而,当复制到其他类型的设备(例如,目的地是套接字)时,这将产生巨大的差异,或者如果您需要确保在其间成功写入某些范围的数据(这意味着同步),这也将有助于写入磁盘。

要添加dvnrrs所说的内容:sendfile更高效(尽管不能总是使用sendfile),因为数据复制不会发生在内核和用户空间之间。通常,当我们使用读写系统调用进行复制时----读将数据从内核空间复制到用户空间;并将数据从用户空间写入到内核空间。

正如其他人所指出的,

Sendfile通常更高效。了解差异的最好方法是在自己的机器上进行测量。

经验法则是尽可能使用sendfile。不过,使用sendfile时不要太聪明。我尝试使用mmapping文件的缓冲区(而不是malloc或带有MAP_ANONYMOUS的mmap)作为处理的暂存空间,这样我就可以在底层FD上调用sendfile,而不是进行写调用。这不是一个好主意。