为什么 memmap IO 在 /proc/[PID]/io 中被忽略

为什么 memmap IO 在 /proc/[PID]/io 中被忽略

我有一个问题 /proc/[PID]/io 和 memmap 我需要分析使用 python 库的应用程序 IO天视
我遇到的问题之一是 /proc/[PID]/io.io 中的 IO 读/写总字节数不正确。

我有一个脚本copy.sh

#!/bin/bash
cp huge.fits huge.2.fits
#python copyfits.py
#python copyfitsMemmapOFF.py
sleep 5 
cat /proc/$$/io

我注释了该cp行以及我想要为每个测试运行的行。

copyfits.py包含:

from astropy.io import fits    
hdulist = fits.open('huge.fits', mode='readonly')
hdulist.writeto('huge.2.fits')
hdulist.close()

copyfitsMemmapOFF.py包含:

    from astropy.io import fits    
    hdulist = fits.open('huge.fits', mode='readonly', memmap=False)
    hdulist.writeto('huge.2.fits')
    hdulist.close()

以下是每个解决方案的 IO 结果:

cp huge.fits huge.2.fits

rchar: 9749929202
wchar: 9749551680

python copyfits.py

**rchar: 8399421**
wchar: 9749551685

python copyfitsMemmapOFF.py

rchar: 9757502959
wchar: 9749551685

据我了解,当使用此变量来监视应用程序读取文件的量时,关闭 memmap 会导致 IO 结果不一致。如何/为什么 memmap 不计入标准 IO 中,我如何才能找到这些 IO ?
因为如果是内核而不是应用程序读取文件,那么文件仍然会被访问。

答案1

/procio跟踪“显式”I/O,IE使用少量系统调用执行 I/O。对于读取,这些是readreadvpreadvsendfilecopy_file_range;您可以使用以下命令查看累积的统计数据add_rcharfs/read_write.c

内存映射文件的 I/O 有很大不同;读取时,它依赖于页面错误处理,并通过许多优化来提高性能(预读等)。您可以通过查看/proc/${pid}/stat(字段 10 和 12)中的页面错误来在某种程度上跟踪这一点。困难的部分是计算出每次页面错误读取了多少数据;我的实验表明每个故障有 64KiB,但我还没有找到可靠的数据来支持这一点(这可能取决于具体情况)。

我不知道有什么现成的方法可以从进程的角度跟踪映射的 I/O (IE读入进程的字节数,无论是否实际发生任何块 I/O)。

准确地计算内存映射读取结果是一个相当棘手的问题,主要是因为计算必须反映意图的方式。io计算程序明确要求读取或写入的字节数;但是当进程将文件映射到其内存中时,读取的粒度由内核而不是读取进程确定。您每 4KiB 只能读取一个字节,内核将为您读取整个文件 — 会计应该反映什么?它无法轻松反映进程在内存中实际读取的字节,这会对性能产生巨大影响(而且不可能在所有体系结构中实现)。

相关内容