¿Por qué tenemos que esperar E / S?

28

Siempre se ha sabido que las operaciones de disco son lentas y sabemos las razones por las que son lentas. Entonces, la pregunta aquí es ¿por qué tenemos que esperar E / S o por qué hay algo como IOWait, etc.?

Quiero decir, me di cuenta de que cuando haces algunas tareas de E / S en segundo plano, tu computadora básicamente se vuelve mucho más lenta, especialmente me di cuenta de que cuando usas Linux, si estás haciendo algunas tareas de E / S más largas , el sistema operativo se vuelve casi inutilizable hasta que se completen.

De hecho, también encontré este tema en un artículo, hay un fragmento:

La espera de E / S es del 12,1%. Este servidor tiene 8 núcleos (a través de cat / proc / cpuinfo). Esto está muy cerca de (1/8 núcleos = 0.125)

Básicamente significa que está ralentizando mucho la computadora, ¿por qué es eso? Quiero decir, está bien, ahora la computadora normal tiene al menos 2 núcleos, a veces 4 o a veces tienen más debido a hyperthreading o algo así. Pero ahora la pregunta es ¿por qué la CPU realmente tiene que permanecer allí, prácticamente sin hacer nada más que solo esperar IO? Me refiero a la idea básica o la arquitectura de la gestión del proceso, ahora no sé si es el sistema operativo el responsable de eso, o si se trata de la parte del hardware, pero debería ser posible que la CPU espere o no verifique regularmente, mientras realiza muchas otras tareas y solo regresa al proceso IO cuando está listo. De hecho, si esa es una tarea tan difícil y la CPU tendría que esperar, ¿por qué no? ¿Eso gestionado por hardware de manera más eficiente entonces? Por ejemplo, podría haber algún tipo de mini CPU que simplemente lo esperaría y entregaría la pequeña parte de los datos a la CPU real tan pronto como vuelva al proceso, por lo que el proceso se repetiría y no tendríamos para dedicar prácticamente todo un núcleo de CPU para el proceso de copia de datos ... ¿O sería yo quien debería inventar este tipo de cosas y obtener un premio nobel por eso? : S

Ahora bien, realmente lo estoy poniendo desde la perspectiva de los observadores y realmente no he profundizado tanto en el tema, pero realmente no entiendo por qué la CPU tiene que funcionar con la velocidad del HDD, aunque podría hacer otra cosa y volver a HDD una vez que esté listo. La idea no es acelerar la aplicación que necesita esa operación de E / S o el proceso de copia o lo que sea, sino la idea es afectar mínimamente el consumo de CPU mientras se realiza esa operación, para que el sistema operativo pueda utilizarla para otros procesos y el usuario no tendría que sentir un retraso general de la computadora al hacer algunas operaciones de copia ...

Arturas M
fuente
41
"mientras que podría hacer otra cosa", como? Necesita trabajar con datos. Si esos datos no están en la memoria caché L1 de la CPU, debe obtenerlos de la memoria caché L2. Si no está en el caché L2, debe obtenerlo del L3 (si tiene uno). Si no está en absoluto en las memorias caché de matriz, debe acceder a la memoria principal. Si no está en la memoria principal ... necesita acceder al HDD.
Oded
39
La computadora hace otra cosa; el núcleo bloquea el hilo hasta que se completa la operación IO, permitiendo que se ejecuten otros hilos / procesos. Pero si todo está esperando en el disco IO, entonces no hay nada más que hacer.
Coronel Treinta y Dos
66
¡Tienes que esperar a que los programas lleguen a la torre de E / S y te envíen sus frisbees!
Almo
1
@immibis ¡Correcto! :)
Almo
2
Por lo general, los sistemas operativos modernos hacen lo que se queja de que no hacen: las operaciones de E / S se envían al hardware apropiado y el hardware genera interrupciones para indicar que las operaciones se han realizado. Los procesos que esperan en IO generalmente se bloquean mientras esperan (esto se puede cambiar). Si muchos procesos están esperando IO y ningún otro proceso tiene algo que hacer para la CPU, entonces no hay mucho que hacer. También podrías terminar en el infierno de intercambio de memoria. Escribir programas para utilizar de manera eficiente CPU, memoria e IO requiere habilidades especiales, y qué más se está ejecutando también afecta lo que funciona mejor.
nategoose

Respuestas:

19

Los esquemas de E / S que está describiendo se usan actualmente en las computadoras.

¿Por qué la CPU realmente tiene que permanecer allí, prácticamente sin hacer nada más que solo esperar IO?

Este es el método de E / S más simple posible: E / S programadas . Muchos sistemas embebidos y microprocesadores de bajo / extremo tienen una sola instrucción de entrada y una única instrucción de salida. El procesador debe ejecutar una secuencia explícita de instrucciones para cada carácter leído o escrito.

pero debería ser posible que la CPU espere o verifique regularmente, mientras realiza muchas otras tareas y solo regresa al proceso IO cuando está listo

Muchas computadoras personales tienen otros esquemas de E / S. En lugar de esperar en un circuito cerrado para que el dispositivo esté listo ( espera ocupada ), la CPU inicia el dispositivo de E / S pidiéndole que genere una interrupción cuando se hace ( interrupción de E / S ).

Aunque la E / S controlada por interrupción es un paso adelante (en comparación con la E / S programada), requiere una interrupción por cada carácter transmitido y es costosa ...

Por ejemplo, podría haber algún tipo de mini CPU que simplemente lo esperaría y entregaría la pequeña parte de los datos a la CPU real tan pronto como vuelva al proceso, por lo que el proceso se repetiría y no tendríamos para dedicar prácticamente todo un núcleo de CPU para el proceso de copia de datos ...

¡La solución a muchos problemas radica en que alguien más haga el trabajo! :-)

El controlador / chip DMA (Acceso directo a memoria) permite E / S programadas, ¡pero que alguien más lo haga!

Con DMA, la CPU solo tiene que inicializar algunos registros y es libre de hacer otra cosa hasta que finalice la transferencia (y se produzca una interrupción).

Incluso DMA no es totalmente gratuito: los dispositivos de alta velocidad pueden usar muchos ciclos de bus para referencias de memoria y referencias de dispositivo ( robo de ciclos ) y la CPU tiene que esperar (el chip DMA siempre tiene una prioridad de bus más alta).

La espera de E / S es del 12,1%. Este servidor tiene 8 núcleos (a través de cat / proc / cpuinfo). Esto está muy cerca de (1/8 núcleos = 0.125)

Creo que esto es de: Comprender la E / S de disco: ¿cuándo debería preocuparse?

Bueno, no es extraño: el sistema (mySQL) debe buscar todas las filas antes de manipular datos y no hay otras actividades.

Aquí no hay un problema de arquitectura de computadora / SO. Así es como se establece el ejemplo.

A lo sumo, podría ser un problema de ajuste RDBMS o un problema de consulta SQL (índice faltante, plan de consulta incorrecto, consulta incorrecta ...)

manlio
fuente
24

Es posible escribir E / S asíncronas donde le dice al sistema operativo que envíe un disco de lectura / escritura y luego haga otra cosa y luego verifique si está hecho. Está lejos de ser nuevo. Un método anterior está utilizando otro hilo para el IO.

Sin embargo, eso requiere que tenga algo que hacer mientras se ejecuta esa lectura y no se le permitirá tocar el búfer que pasó para obtener el resultado.

También es mucho más fácil programar cuando asumes que todo está bloqueando IO.

Cuando llama a una función de lectura de bloqueo, sabe que no volverá hasta que se haya leído algo e inmediatamente después de que pueda comenzar a procesarlo.

El típico ciclo de lectura es un buen ejemplo.

//variables that the loop uses
char[1024] buffer;
while((read = fread(buffer, 1024, 1, file))>0){
    //use buffer
}

De lo contrario, debe guardar el estado actual de la función (generalmente en forma de una devolución de llamada + puntero de datos de usuario) y pasarlo + identificador de la operación de lectura a un select()bucle de tipo. Allí, si finaliza una operación, asignará el identificador de la operación de lectura al indicador de devolución de llamada + datos e invocará la devolución de llamada con información de la operación completada.

void callback(void* buffer, int result, int fd, void* userData){
    if(result<=0){
    //done, free buffer and continue to normal processing
    }
    //use buffer

    int readID = async_read(fd, buffer, userData->buff_size);
    registerCallback(readId, callback, userData);
}

Esto también significa que cada función que podría terminar usando esa lectura asíncrona necesitaría poder manejar una continuación asíncrona. Ese es un cambio no trivial en la mayoría de los programas, le preguntas a las personas que tratan de entrar en C # asíncrono al respecto.


Sin embargo, IO síncrono versus IO asíncrono no es la causa de la desaceleración general. Intercambiar páginas también es una operación que necesita esperar en IO. El programador simplemente cambiará a otro programa que no esté esperando IO si uno lo está ( IO wait es cuando el procesador está inactivo y hay una operación IO pendiente ).

El verdadero problema es que tanto el disco duro como la CPU usan el mismo canal para comunicarse con la RAM ; El bus de memoria. Y a menos que esté utilizando RAID, solo hay un único disco para obtener los datos. Esto empeora si también está utilizando una aplicación de gráficos intensivos, entonces la comunicación con la GPU también interferirá.

En otras palabras, el verdadero cuello de botella está probablemente en el hardware y no en el software.

monstruo de trinquete
fuente
66
"Sin embargo, la E / S sincrónica versus la E / S asincrónica no es la causa de la desaceleración general". Entonces, ¿por qué decidiste enfocarte en este tema relativamente avanzado cuando la pregunta es sobre lo básico?
svick
1
Probablemente deberías mencionar algo sobre DMA
Alec Teal
2
Dato curioso: en realidad hay un mecanismo realmente antiguo que permite que los programas hagan otra cosa mientras realizan E / S sin tener que lidiar con devoluciones de llamada; Se llama hilos .
user253751
2
Buena discusión sobre los pros / contras de sync / async IO. ¿Pero estás seguro de que esa es la razón de la desaceleración? En general, encuentro que las ralentizaciones bajo una gran carga de E / S se deben en primer lugar a un software mal diseñado, o cuando ese no es el caso, entonces porque el sistema está usando un solo disco lento (es decir, que no es SSD), y todo está tratando de acceder al mismo tiempo . Culparía de un cuello de botella a la capacidad del disco para atender solicitudes antes de culpar a la saturación del bus de memoria. Necesita un almacenamiento realmente avanzado para saturar un bus de memoria moderno.
Aroth
9

Tenga fe en que el procesamiento de otras cosas mientras espera E / S es bastante ágil, lo más ágil posible. Cuando ve que su computadora está esperando E / S solo el 12.1% del tiempo, significa que de hecho está haciendo muchas otras cosas en paralelo. Si realmente tuviera que esperar E / S sin hacer nada más, estaría esperando el 99.9% del tiempo, así de lenta es la E / S.

La única forma de hacer más cosas en paralelo es prediciendo lo que el usuario podría querer hacer a continuación, y todavía no somos muy buenos en ese tipo de predicción. Por lo tanto, si el usuario realiza una operación que requiere que un sector en particular se lea desde el disco duro, y ese sector aún no está en la memoria caché, entonces el sistema operativo comenzará el largo proceso de lectura de ese sector, y intentará ver si hay algo más que hacer mientras tanto. Si hay otro usuario que quiere un sector diferente, también pondrá en cola esa solicitud. En algún momento, todas las solicitudes se han puesto en cola y no hay nada que podamos hacer más que esperar a que se satisfaga la primera antes de que podamos continuar. Es solo un hecho de la vida.

EDITAR:

Encontrar una solución al problema de cómo hacer otras cosas mientras hago E / S sería una hazaña admirable, porque al mismo tiempo sería una solución al problema de cómo hacer otras cosas mientras está inactivo. Sería una hazaña increíble, porque significaría que encontraría trabajo para su computadora, mientras que no tiene ninguno.

Verá, esto es lo que está sucediendo: su computadora está sentada el 99.99% del tiempo, sin hacer nada. Cuando le das algo que hacer, va y lo hace. Si al hacerlo tiene que esperar E / S, se queda allí y espera. Si tiene algo más que hacer mientras hace E / S, también lo hace. Pero si no tiene nada más que hacer además de E / S, entonces tiene que sentarse allí y esperar a que se complete la E / S. No hay forma de evitar eso, aparte de inscribirse en SETI @ Home.

Mike Nakis
fuente
Bueno, el ejemplo del 12.1% era de un sitio web y el ejemplo fue tomado de un servidor con 8 núcleos, la idea era que casi un núcleo completo estaba reservado para esas operaciones, seguro que los otros núcleos eran libres de hacer cualquier cosa y con 8 núcleos estás bien, pero ¿qué pasa si solo tienes un núcleo? : /
Arturas M
3
@ArturasM O ha entendido mal lo que dice el sitio web, o el autor del sitio web ha entendido mal algo. Una computadora con un solo núcleo pasaría menos tiempo esperando E / S (ya que todas las tareas que no esperan IO, que se ejecutan en los otros núcleos mientras un núcleo permanece inactivo, tendrían que ejecutarse en el único núcleo). La E / S tarda una cierta cantidad de tiempo en suceder, ya sea que la espere o no; tener tiempo para esperar es un síntoma de no tener nada más que ver con ese tiempo.
Random832
6

El sistema operativo (a menos que sea un sistema integrado de muy bajo nivel o algo similar exótico) ya se encarga de esto: si su aplicación tiene que esperar E / S, generalmente se bloqueará en esa E / S y algún otro hilo o aplicación se convertirá activo. El planificador decide cuál.

Solo si no hay otro subproceso o aplicación que pueda estar ejecutándose, realmente está acumulando tiempo de espera. En el artículo que citó (gracias a @manlio por el enlace), ese es el caso: tiene 12.1% de espera frente a 87.4% de inactividad, lo que significa que un núcleo está esperando que se complete la E / S mientras que el resto no hace nada en absoluto. Déle a ese sistema algo que hacer, preferiblemente varias cosas, y el porcentaje de espera debería caer.

Uno de los objetivos principales del diseño de aplicaciones de hoy es garantizar que incluso si solo hay una aplicación en ejecución, e incluso si esa aplicación en algún momento está esperando E / S, la aplicación aún puede continuar en otra parte del trabajo. Los subprocesos son un enfoque para esto, la E / S sin bloqueo es otra, pero depende mucho del tipo de trabajo que esté haciendo, si realmente puede hacer algo sin los datos que está esperando.

cuando usa Linux, si está haciendo algunas tareas de E / S más largas, el sistema operativo se vuelve casi inutilizable hasta que se completen.

Eso suele ser una indicación de alguna situación vinculada a E / S. Me atrevo a decir que el sistema no se está ralentizando porque no puede hacer suficiente procesamiento de la CPU. Lo más probable es que sea lento porque varias cosas dependen de los datos del HDD, que está ocupado en ese momento. Estas pueden ser aplicaciones que desea ejecutar pero que tienen que cargar sus archivos ejecutables, archivos de biblioteca, iconos, fuentes y otros recursos. Es posible que se trate de aplicaciones que ya está ejecutando, pero que han intercambiado parte de su memoria y ahora necesitan volver a intercambiarlas para continuar. Puede ser un demonio que, por una razón u otra, piensa que no solo tiene que escribir una línea en un archivo de registro, sino que en realidad vaciar ese archivo de registro antes de responder alguna solicitud.

Puede usar herramientas como iotoppara ver cómo se asigna la capacidad de E / S a los procesos y ionicepara establecer prioridades de E / S para los procesos. Por ejemplo, en una máquina de escritorio, puede clasificar todo el procesamiento de datos en masa en la idleclase de programación, de modo que en el momento en que alguna aplicación interactiva necesite ancho de banda de E / S, el procesamiento en masa se suspende hasta que la aplicación interactiva esté terminada.

MvG
fuente
5

Depende de su código de aplicación. Supongo que su código se está ejecutando en Linux.

Se podría utilizar multi threading (por ejemplo, POSIX pthreads ) para tener discusiones en términos de computación que hacen un poco de cálculo y en otros hilos con destino a IO están haciendo el IO (y en espera de la misma). Incluso podría hacer que su aplicación ejecute varios procesos que se comunican con la comunicación entre procesos (IPC), consulte pipe (7) , fifo (7) , socket (7) , unix (7) , shm_overview (7) , sem_overview (7) , mmap (2) , eventfd (2) y lea Programación avanzada de Linux, etc.

Puede usar E / S sin bloqueo , por ejemplo, pasar O_NOBLOCKpara abrir (2), etc., etc., etc. entonces necesitará sondear (2) y / o usar la SIGIO señal (7) ... y manejar el EWOULDBLOCKerror de lectura (2), etc.

Puede usar POSIX IO asíncrono, vea aio (7)

Para acceder a los archivos, puede dar pistas sobre el caché de la página , por ejemplo, con madvise (2) después de mmap (2) y con posix_fadvise (2) ; ver también el readahead específico de Linux (2)

Pero eventualmente llegaría a un cuello de botella de hardware (el bus, la RAM, etc.). Ver también ionice (1)

Basile Starynkevitch
fuente
1

Agrego otro punto de vista que otros, quizás controvertido:

Su problema típico de los sistemas operativos Linux. Retraso específico (Buscar "retraso de mouse de Linux"). Windows no tiene este problema. Tengo arranque dual Windows 7 y Linux Mint. Incluso cuando se realiza una operación intensiva de disco en Windows, Windows se siente suave, el mouse se mueve normalmente. En Linux oppositelly no se siente tan suave y el mouse a veces se retrasa incluso durante la navegación web normal.

Probablemente se deba a una filosofía e historia diferentes de estos dos sistemas. Desde el principio, Windows está diseñado para usuarios comunes, sus sistemas de operaciones gráficas en principio. Y para los usuarios de Windows, el comportamiento no uniforme del sistema y la detención del movimiento del mouse es señal de que algo está mal. Por lo tanto, los programadores de Microsofts trabajaron duro para diseñar todo el sistema para minimizar los casos en que los sistemas se sienten lentos. Al contrario, Linux no es inicialmente un sistema gráfico, el escritorio es solo una adición de terceros aquí. Y Linux está diseñado en principio para hackers que usan la línea de comandos. Haz que las cosas hagan filosofía. Linux simplemente no está diseñado para un comportamiento suave en mente, los sentimientos no importan aquí.

Nota: No estoy diciendo que Windows es mejor que Linux, digo que simplemente tienen una filosofía general diferente, que en un entorno complejo puede conducir a diferentes comportamientos / sentimientos de alto nivel de estos sistemas.

usuario3123061
fuente
El retraso del mouse en Linux probablemente podría evitarse o reducirse mediante una configuración cuidadosa del sistema (es decir, usando nicey ioniceen procesos hambrientos). Y sí uso Linux y casi nunca experimenté ese retraso del mouse de Linux (excepto cuando sobrecargué mi computadora ...)
Basile Starynkevitch
Por cierto, Linux es principalmente un sistema operativo de servidor.
Basile Starynkevitch
Notaré que he experimentado un retraso en la interfaz de usuario y el mouse en Windows 7, incluso en momentos en que el Administrador de tareas y el Monitor de recursos indicaron un bajo uso de memoria y una baja actividad de la CPU y el disco.
8bittree