Eu tenho um problema /proc/[PID]/io e memmap, preciso criar o perfil do aplicativo IO que usa a biblioteca python astropy .
Um dos problemas que tenho é que os bytes totais de leitura/gravação de IO estão incorretos em /proc/[PID]/io.
Eu tenho um roteiro copy.sh
:
#!/bin/bash
cp huge.fits huge.2.fits
#python copyfits.py
#python copyfitsMemmapOFF.py
sleep 5
cat /proc/$$/io
Eu comento a cp
linha e a linha que desejo executar para cada teste.
copyfits.py
contém:
from astropy.io import fits
hdulist = fits.open('huge.fits', mode='readonly')
hdulist.writeto('huge.2.fits')
hdulist.close()
copyfitsMemmapOFF.py
contém:
from astropy.io import fits
hdulist = fits.open('huge.fits', mode='readonly', memmap=False)
hdulist.writeto('huge.2.fits')
hdulist.close()
aqui estão os resultados de IO para cada solução:
cp huge.fits huge.2.fits
rchar: 9749929202
wchar: 9749551680
python copyfits.py
**rchar: 8399421**
wchar: 9749551685
python copyfitsMemmapOFF.py
rchar: 9757502959
wchar: 9749551685
Entendo que o memmap desativado levará a resultados de E/S inconsistentes ao usar essa variável para monitorar quanto o aplicativo lê arquivos. Como/por que memmap não são contados no IO padrão e como posso descobrir sobre esses IO?
Porque se for o kernel em vez do arquivo de leitura do aplicativo, o arquivo ainda será acessado.
/proc
'sio
apenas rastreia I/O “explícito”, ou seja , I/O executado usando um pequeno número de chamadas de sistema. Para leituras, sãoread
,readv
,preadv
,sendfile
ecopy_file_range
; você pode ver as estatísticas acumuladas usandoadd_rchar
emfs/read_write.c
.A E/S para arquivos mapeados em memória é bem diferente; ao ler, ele depende do tratamento de faltas de página, com várias otimizações para aumentar o desempenho (leitura antecipada, etc.). Você pode rastrear isso até certo ponto observando as faltas de página nos
/proc/${pid}/stat
(campos 10 e 12). A parte difícil é descobrir quantos dados são lidos com cada falha de página; meus experimentos sugerem 64 KiB por falha, mas não encontrei dados concretos para fazer backup disso (e provavelmente depende das circunstâncias).Não conheço nenhuma maneira pronta para uso de rastreamento de E/S mapeada do ponto de vista do processo ( ou seja, bytes lidos no processo, independentemente de qualquer bloco de E/S realmente ter ocorrido).
Contabilizar as leituras mapeadas na memória com precisão acaba sendo um problema bastante difícil, principalmente por causa da maneira como a contabilização reflete a intenção.
io
conta os bytes que um programa pediu explicitamente para ler ou escrever; mas quando um processo mapeia um arquivo em sua memória, as leituras ocorrem com uma granularidade determinada pelo kernel, não pelo processo de leitura. Você pode ler apenas um byte a cada 4KiB e o kernel lerá o arquivo inteiro para você - o que a contabilidade deve refletir? Ele não pode refletir facilmente os bytes realmente lidos na memória pelo processo, o que teria um grande impacto no desempenho (além de ser impossível de implementar em todas as arquiteturas).