栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

在Linux中复制文件的最有效方法

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

在Linux中复制文件的最有效方法

不幸的是,您不能

sendfile()
在这里使用,因为目的地不是套接字。(名称
sendfile()
来自
send()
+“文件”)。

对于零复制,可以

splice()
按照@Dave的建议使用。(除非它不是零拷贝;它将是从源文件的页面缓存到目标文件的页面缓存的“一个副本”。)

但是…(a)

splice()
是特定于Linux的;(b)只要正确使用便携式接口,几乎可以肯定也可以做到。

简而言之,将

open()
+
read()
+
write()
与一个 小的 临时缓冲区一起使用。我建议8K。因此,您的代码将如下所示:

int in_fd = open("source", O_RDONLY);assert(in_fd >= 0);int out_fd = open("dest", O_WRONLY);assert(out_fd >= 0);char buf[8192];while (1) {    ssize_t read_result = read(in_fd, &buf[0], sizeof(buf));    if (!read_result) break;    assert(read_result > 0);    ssize_t write_result = write(out_fd, &buf[0], read_result);    assert(write_result == read_result);}

通过此循环,您将把8k从in_fd页面缓存复制到CPU
L1缓存中,然后将其从L1缓存写入out_fd页面缓存中。然后,您将用文件中的下一个8K块覆盖L1缓存的该部分,依此类推。最终结果是,输入的数据

buf
根本不会真正存储在主存储器中(最后可能一次除外);从系统RAM的角度来看,这与使用“
zero-copy”一样好
splice()
。另外,它非常适合任何POSIX系统。

请注意,此处的小缓冲区是关键。典型的现代CPU的L1数据高速缓存大约为32K,因此,如果将缓冲区设置得太大,这种方法会比较慢。可能慢得多。因此,将缓冲区保持在“几千字节”范围内。

当然,除非您的磁盘子系统非常快,否则内存带宽可能不是您的限制因素。因此,我建议

posix_fadvise
让内核知道您要做什么:

posix_fadvise(in_fd, 0, 0, POSIX_FADV_SEQUENTIAL);

这将向Linux内核暗示其预读机制应该非常积极。

我还建议使用

posix_fallocate
来为目标文件预分配存储空间。这将提前告诉您是否会用完磁盘。对于具有现代文件系统(例如XFS)的现代内核,它将有助于减少目标文件中的碎片。

我最后建议的是

mmap
。由于TLB颠簸,它通常是最慢的方法。(非常新的具有“透明大页面”的内核可能会减轻这种情况;我最近没有尝试过。但是它过去肯定很糟糕。因此,
mmap
如果您有大量时间进行基准测试和使用新内核,我只会打扰测试。)

[更新]

注释中存在一个问题,即

splice
从一个文件到另一个文件是否为零拷贝。Linux内核开发人员将此称为“页面窃取”。的手册页
splice
和内核源代码中的注释均表示该
SPLICE_F_MOVE
标志应提供此功能。

不幸的是,支持

SPLICE_F_MOVE
被猛拉在2.6.21(早在2007年),从来没有更换。(内核源代码中的注释从未更新。)如果您搜索内核源代码,您会发现
SPLICE_F_MOVE
实际上并没有在任何地方引用它。我可以找到的最后一条消息(来自2008年)说,它是“等待替换”。

底线是

splice
从一个文件到另一个调用
memcpy
以移动数据。它 不是
零拷贝。这并不比在使用小缓冲区
read
/的用户空间中做的更好
write
,所以您最好还是坚持使用标准的可移植接口。

如果曾经将“页面窃取”重新添加到Linux内核中,那么

splice
它将带来更大的好处。(甚至在今天,当目的地是套接字时,您也会得到真正的零副本,从而使它
splice
更具吸引力。)但是,出于这个问题的目的,
splice
并不能为您带来多少好处。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/405693.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号