Linux read()是否将数据复制到进程地址空间

时间:2017-04-25 18:50:06

标签: linux caching io

我试图理解read()和mmap()之间的具体区别。我对两者都有基本/正确的理解但是有一些基本的东西我没有得到。

我想这里的答案很简单,但问题是:

假设你打开一个文件“test.txt”,它不存在于文件缓存中,你想要读取前64个字节。我的理解是,前4k字节被读入页面缓存,然后64字节被复制到缓冲区中以进行read()调用。

我的问题:

1)当您通过read()读入数据并且4k存储在文件系统缓存中时,是否占用了进程的虚拟内存地址空间,或者只是可以/将被分页的磁盘缓存空间后来?我知道mmap会将文件(或文件的一部分)映射到进程地址空间,但我无法弄清楚read()是否使用进程地址空间。我的猜测是不是因为read()不允许你随机访问文件的部分(这是正确的吗?)。

2)将64个字节复制到由进程使用的read()返回的缓冲区中,这些数据会占用进程地址空间还是只占用磁盘空间缓存?

1 个答案:

答案 0 :(得分:1)

  

我的理解是,前4k字节被读入页面缓存,然后64字节被复制到缓冲区中以进行read()调用。

一般来说,这是正确的。 (但总有例外 - 在这种情况下direct I/O。除非你正在处理一些I / O边案,否则你真的不需要担心这个问题......)

  

当您通过read()读入数据并且4k存储在文件系统缓存中时,这是否占用了进程的虚拟内存地址空间,或者只是可能/将要的磁盘缓存空间以后分页了?

后者 - 磁盘缓存是内核空间中的内存,它可以缓存磁盘上的数据内容。它可以被分页(就像大多数内存页面一样)。

  

复制到由进程使用的read()返回的缓冲区中的64个字节是否会占用进程地址空间或仅占用磁盘空间缓存?

将数据从磁盘缓存(内核内存)复制到用户空间中的缓冲区中。所以数据都在这两个地方。 (这是直接I / O的原因 - 额外的复制步骤和数据本身的额外副本被消除)

I / O性能是一个复杂的主题。在一个案例中最快的可能在另一个案例中最快。从CPU速度到内存带宽再到PCI总线带宽,再到磁盘控制器特性,再到SATA / SAS / SCSI / FC / iSCSI带宽以及延迟到实际物理磁盘性能等等都很重要。 如何将数据布置在磁盘上。 如何访问数据很重要。几乎不可能说mmap()read()更快 - 或者反之亦然。

考虑获得最佳的I / O性能,与高端立体声系统上的阻抗匹配扬声器相似,以获得最佳音效,但是有更多的变量会影响最好的音频效果。回答。要获得绝对最佳性能,所有必须匹配 - 从物理磁盘上的数据的实际布局到用户空间应用程序的精确模式用来访问数据。

总的来说,它真的不值得烦恼 - 几乎每一个开箱即用的设置都会让你至少80%左右的硬件可以提供的最大可能性能,只要你不要#39;做一些不好的事情,比如一次反向读取一个文件。