¿Por qué las lecturas de / dev / zero no cuentan como IO_RBYTES?

25

Estoy vaciando un disco duro en algunos SO Linux 4.x usando este comando:

sudo sh -c 'pv -pterb /dev/zero > /dev/sda'

Y abrí otro tty y comencé a sudo htopnotar esto:

  PID USER      PRI  NI CPU%   RES   SHR   IO_RBYTES   IO_WBYTES S   TIME+  Command
 4598 root       20   0 15.5  1820  1596        4096    17223823 D  1:14.11 pv -pterb /dev/zero

El valor de IO_WBYTESparece bastante normal, pero IO_RBYTESpermanece en 4 KiB y nunca cambia.

Ejecuté algunos otros programas, por ejemplo

dd if=/dev/zero of=/dev/zero
cat /dev/zero > /dev/zero

y me sorprendió ver que ninguno de ellos genera mucho IO_RBYTESo IO_WBYTES.

Creo que esto no es específico de ningún programa, pero ¿por qué no lee /dev/zeroy escribe para /dev/{zero,null}contar como bytes de E / S?

iBug
fuente
55
Tengo curiosidad, ¿por qué crees que deberían contar como E / S?
Marcelm
1
@marcelm Creo que cualquier entrada / salida debe contar como E / S, incluido el archivo R / W, la E / S de red y muchos más.
iBug
pero esas operaciones realizan E / S al hardware (disco y la tarjeta de red, respectivamente), y tienen que viajar a través de algún bus de E / S (como PCI-express), todo lo cual puede ser un cuello de botella significativo. Escribe, por ejemplo, /dev/nullpara no terminar la interfaz con ese hardware y no obstruir los buses de E / S. Llevado al extremo; ¿son las lecturas / escrituras a / desde la memoria también E / S? Por supuesto, no hay una delineación difícil para estas cosas, y todo depende de la perspectiva que tome en estas cosas y de cuán útil esa perspectiva termine siendo para usted.
Marcelm
1
Tenga en cuenta que mi primer comentario tenía la intención de provocarle a usted (y a otros) a pensar en esas perspectivas y descubrir por qué está tomando su perspectiva. No pretendo insinuar que estás equivocado; Ni siquiera creo que la situación sea tan en blanco y negro. Pero personalmente, estaría mucho más interesado en las estadísticas de E / S para el hardware real (que muy bien puede ser un cuello de botella) que /dev/{null,zero}(que generalmente no es un cuello de botella). Sin embargo, esa es solo mi perspectiva :)
marcelm
1
@marcelm Pero inicialmente estaba pensando en eso read(2)y write(2)cuenta como E / S, lo cual es muy razonable en su propio sentido.
iBug

Respuestas:

54

Cuentan como E / S, pero no del tipo medido por los campos que está viendo.

En htop, IO_RBYTESy IO_WBYTESmostrar la read_bytesy write_bytescampos de /proc/<pid>/io, y esos campos miden bytes que van a través de la capa de bloque. /dev/zerono involucra la capa de bloque, por lo que las lecturas de ella no aparecen allí.

Para ver las E / S desde /dev/zero, debe mirar los campos rchary , que se muestran como y :wchar/proc/<pid>/iohtopRCHARWCHAR

rchar : caracteres leídos

El número de bytes que esta tarea ha provocado que se lean del almacenamiento. Esto es simplemente la suma de bytes a los que pasó este proceso read(2)y llamadas similares al sistema. Incluye cosas como la E / S del terminal y no se ve afectado por si se requirió o no la E / S del disco físico real (la lectura podría haberse satisfecho desde el caché de página).

wchar : caracteres escritos

El número de bytes que esta tarea ha causado, o hará que se escriban en el disco. Advertencias similares se aplican aquí como con rchar.

Ver man 5 procy man 1 htoppara más detalles.

Stephen Kitt
fuente
Entonces es rchary wchareso cuenta bytes de llamadas a read(2)y write(2), ¿verdad?
iBug
Si, eso es correcto.
Stephen Kitt
99
Habla sobre frases engañosas en la descripción de rchar . ¡Todo lo que pasó read()definitivamente no es "leído desde el almacenamiento "!
ilkkachu
2
@ilkkachu por storageque quiere decir "cualquier línea de autobús concebible", independientemente de que el almacenamiento en cuestión es físico o virtual o mmap'd o una toma virtual o en la caché L1 - está justo fuera nada de memoria mapeada de ese programa, incluyendo compartida
gato