![为什么 memmap IO 在 /proc/[PID]/io 中被忽略](https://linux22.com/image/132206/%E4%B8%BA%E4%BB%80%E4%B9%88%20memmap%20IO%20%E5%9C%A8%20%2Fproc%2F%5BPID%5D%2Fio%20%E4%B8%AD%E8%A2%AB%E5%BF%BD%E7%95%A5.png)
我有一个问题 /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
/proc
只io
跟踪“显式”I/O,IE使用少量系统调用执行 I/O。对于读取,这些是read
、readv
、preadv
、sendfile
和copy_file_range
;您可以使用以下命令查看累积的统计数据add_rchar
在fs/read_write.c
。
内存映射文件的 I/O 有很大不同;读取时,它依赖于页面错误处理,并通过许多优化来提高性能(预读等)。您可以通过查看/proc/${pid}/stat
(字段 10 和 12)中的页面错误来在某种程度上跟踪这一点。困难的部分是计算出每次页面错误读取了多少数据;我的实验表明每个故障有 64KiB,但我还没有找到可靠的数据来支持这一点(这可能取决于具体情况)。
我不知道有什么现成的方法可以从进程的角度跟踪映射的 I/O (IE读入进程的字节数,无论是否实际发生任何块 I/O)。
准确地计算内存映射读取结果是一个相当棘手的问题,主要是因为计算必须反映意图的方式。io
计算程序明确要求读取或写入的字节数;但是当进程将文件映射到其内存中时,读取的粒度由内核而不是读取进程确定。您每 4KiB 只能读取一个字节,内核将为您读取整个文件 — 会计应该反映什么?它无法轻松反映进程在内存中实际读取的字节,这会对性能产生巨大影响(而且不可能在所有体系结构中实现)。