我有一个问题 /proc/[PID]/io 和 memmap 我需要分析使用 python 库astropy的应用程序 IO 。
我遇到的问题之一是/proc/[PID]/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 ?
因为如果它是内核而不是应用程序读取文件,则仍然可以访问该文件。
/proc
io
只跟踪“显式”I/O,即使用少量系统调用执行的I/O。对于读取,它们是read
,readv
,preadv
,sendfile
, 和copy_file_range
;add_rchar
您可以使用in查看累积的统计信息fs/read_write.c
。内存映射文件的 I/O 完全不同;
/proc/${pid}/stat
读取时,它依赖于页面错误处理,并进行了许多优化以提高性能(预读等)。您可以通过查看(字段 10 和 12)中的页面错误在某种程度上跟踪它。困难的部分是弄清楚每个页面错误读取了多少数据;我的实验表明每个故障 64KiB,但我还没有找到支持它的硬数据(这可能取决于具体情况)。从进程的角度来看,我不知道有任何现成的跟踪映射 I/O 的方法(即读入进程的字节,无论是否实际发生了任何块 I/O)。
准确计算内存映射读取是一个相当棘手的问题,主要是因为计算必须反映意图的方式。
io
计算程序明确要求读取或写入的字节数;但是当一个进程将一个文件映射到它的内存中时,读取发生的粒度由内核决定,而不是读取进程。你可以每 4KiB 读取一个字节,内核会为你读取整个文件——会计应该反映什么?它不能轻易地反映进程在内存中实际读取的字节数,这会产生巨大的性能影响(除了不可能在所有架构中实现之外)。