¿Qué significan los términos "vinculado a la CPU" y "vinculado a E / S"?
optimization
terminology
Desarrollador
fuente
fuente
Respuestas:
Es bastante intuitivo:
Un programa está vinculado a la CPU si iría más rápido si la CPU fuera más rápida, es decir, pasa la mayor parte de su tiempo simplemente usando la CPU (haciendo cálculos). Un programa que calcula nuevos dígitos de π generalmente estará enlazado a la CPU, solo está haciendo números crujientes.
Un programa está vinculado a E / S si iría más rápido si el subsistema de E / S fuera más rápido. A qué sistema de E / S se refiere puede variar; Normalmente lo asocio con el disco, pero, por supuesto, las redes o la comunicación en general también son comunes. Un programa que busca datos en un archivo enorme podría estar vinculado a E / S, ya que el cuello de botella es la lectura de los datos del disco (en realidad, este ejemplo es quizás algo anticuado en estos días con cientos de MB / s viniendo de SSDs).
fuente
CPU Bound significa que la velocidad a la que progresa el proceso está limitada por la velocidad de la CPU. Es probable que una tarea que realiza cálculos en un pequeño conjunto de números, por ejemplo, multiplicar matrices pequeñas, esté vinculada a la CPU.
I / O Bound significa que la velocidad a la que progresa un proceso está limitada por la velocidad del subsistema de E / S. Es probable que una tarea que procesa datos del disco, por ejemplo, contar el número de líneas en un archivo esté vinculada a E / S.
Memoria enlazada significa que la velocidad a la que progresa un proceso está limitada por la cantidad de memoria disponible y la velocidad de acceso a esa memoria. Es probable que una tarea que procesa grandes cantidades de datos en la memoria, por ejemplo, multiplicar matrices grandes, sea Memory Bound.
Límite de caché significa la velocidad a la que el progreso de un proceso está limitado por la cantidad y la velocidad del caché disponible. Una tarea que simplemente procesa más datos de los que caben en el caché estará vinculada al caché.
I / O Bound sería más lento que Memory Bound sería más lento que Cache Bound sería más lento que CPU Bound.
La solución para estar vinculado a E / S no es necesariamente obtener más memoria. En algunas situaciones, el algoritmo de acceso podría diseñarse en torno a las limitaciones de E / S, memoria o caché. Ver caché algoritmos ajenos .
fuente
Multihilo
En esta respuesta, investigaré un caso de uso importante para distinguir entre el trabajo acotado de CPU frente a IO: al escribir código multiproceso.
Ejemplo de enlace de E / S de RAM: suma de vectores
Considere un programa que suma todos los valores de un solo vector:
Paralelizar eso al dividir la matriz equitativamente para cada uno de sus núcleos es de utilidad limitada en los escritorios modernos comunes.
Por ejemplo, en mi Ubuntu 19.04, laptop Lenovo ThinkPad P51 con CPU: CPU Intel Core i7-7820HQ (4 núcleos / 8 hilos), RAM: 2x Samsung M471A2K43BB1-CRC (2x 16GiB) Obtengo resultados como este:
Trazar datos .
Sin embargo, tenga en cuenta que hay mucha variación entre la ejecución. Pero no puedo aumentar el tamaño de la matriz mucho más ya que ya estoy en 8GiB, y no estoy de humor para estadísticas en varias ejecuciones hoy. Sin embargo, esto parecía una carrera típica después de hacer muchas carreras manuales.
Código de referencia:
pthread
Código fuente POSIX C utilizado en el gráfico.Y aquí hay una versión de C ++ que produce resultados análogos.
guión de la trama
No conozco suficiente arquitectura de computadora para explicar completamente la forma de la curva, pero una cosa está clara: ¡el cálculo no se vuelve 8 veces más rápido como se esperaba ingenuamente debido a que uso todos mis 8 hilos! Por alguna razón, 2 y 3 subprocesos fueron óptimos, y agregar más solo hace que las cosas sean mucho más lentas.
Compare esto con el trabajo vinculado a la CPU, que en realidad se vuelve 8 veces más rápido: ¿qué significan 'real', 'user' y 'sys' en la salida del tiempo (1)?
La razón es que todos los procesadores comparten un solo bus de memoria que se vincula a la RAM:
entonces el bus de memoria se convierte rápidamente en el cuello de botella, no en la CPU.
Esto sucede porque agregar dos números toma un solo ciclo de CPU, las lecturas de memoria toman alrededor de 100 ciclos de CPU en el hardware de 2016.
Por lo tanto, el trabajo de CPU realizado por byte de datos de entrada es demasiado pequeño, y llamamos a esto un proceso vinculado a IO.
La única forma de acelerar aún más ese cálculo sería acelerar los accesos a la memoria individual con un nuevo hardware de memoria, por ejemplo, memoria multicanal .
Actualizar a un reloj de CPU más rápido, por ejemplo, no sería muy útil.
Otros ejemplos
la multiplicación de matrices está vinculada a la CPU en RAM y GPU. La entrada contiene:
números, pero:
se hacen multiplicaciones, y eso es suficiente para que la paralelización valga la pena para la práctica N. grande
Es por eso que existen bibliotecas de multiplicación de matriz de CPU paralelas como las siguientes:
El uso de caché hace una gran diferencia en la velocidad de las implementaciones. Consulte, por ejemplo, este ejemplo didáctico de comparación de GPU .
Ver también:
La creación de redes es el ejemplo prototípico de enlace de E / S.
Incluso cuando enviamos un solo byte de datos, todavía lleva mucho tiempo llegar a su destino.
Paralelizar las solicitudes de redes pequeñas, como las solicitudes HTTP, puede ofrecer grandes ganancias de rendimiento.
Si la red ya está a plena capacidad (por ejemplo, descargando un torrent), la paralelización puede aumentar la latencia (por ejemplo, puede cargar una página web "al mismo tiempo").
Una operación simulada de CPU C ++ que toma un número y lo cruje mucho:
La ordenación parece ser CPU basada en el siguiente experimento: ¿Ya están implementados los algoritmos paralelos de C ++ 17? que mostró una mejora del rendimiento 4x para la ordenación paralela, pero también me gustaría tener una confirmación más teórica
Cómo saber si estás vinculado a la CPU o IO
IO sin RAM enlazado como disco, red:,
ps aux
luego theck ifCPU% / 100 < n threads
. En caso afirmativo, está sujeto a E / S, por ejemplo, los bloqueosread
solo esperan datos y el planificador se salta ese proceso. Luego use otras herramientas comosudo iotop
para decidir qué IO es exactamente el problema.O, si la ejecución es rápida y parametriza el número de subprocesos, puede verlo fácilmente a partir de
time
que el rendimiento mejora a medida que aumenta el número de subprocesos para el trabajo vinculado a la CPU: ¿Qué significan 'real', 'usuario' y 'sys' en la salida del tiempo (1)?Enlace RAM-IO: más difícil de determinar, ya que el tiempo de espera RAM se incluye en las
CPU%
mediciones, consulte también:Algunas opciones:
GPU
Las GPU tienen un cuello de botella de E / S cuando transfiere los datos de entrada desde la RAM legible por CPU normal a la GPU.
Por lo tanto, las GPU solo pueden ser mejores que las CPU para las aplicaciones vinculadas a la CPU.
Sin embargo, una vez que los datos se transfieren a la GPU, pueden operar en esos bytes más rápido que la CPU, porque la GPU:
tiene más localización de datos que la mayoría de los sistemas de CPU, por lo que se puede acceder a los datos más rápido para algunos núcleos que para otros
explota el paralelismo de datos y sacrifica la latencia simplemente saltando cualquier dato que no esté listo para ser operado de inmediato.
Dado que la GPU tiene que operar con datos de entrada paralelos grandes, es mejor simplemente pasar a los siguientes datos que podrían estar disponibles en lugar de esperar a que los datos actuales estén disponibles y bloquear todas las demás operaciones como lo hace la CPU en su mayoría
Por lo tanto, la GPU puede ser más rápida que una CPU si su aplicación:
Estas opciones de diseño originalmente apuntaban a la aplicación de renderizado 3D, cuyos pasos principales son los que se muestran en ¿Qué son los sombreadores en OpenGL y para qué los necesitamos?
y así concluimos que esas aplicaciones están vinculadas a la CPU.
Con el advenimiento de GPGPU programable, podemos observar varias aplicaciones de GPGPU que sirven como ejemplos de operaciones vinculadas a la CPU:
Procesamiento de imágenes con sombreadores GLSL?
Las operaciones locales de procesamiento de imágenes, como un filtro de desenfoque, son de naturaleza muy paralela.
¿Es posible construir un mapa de calor a partir de datos de puntos a 60 veces por segundo?
Trazado de gráficos de mapa de calor si la función trazada es lo suficientemente compleja.
https://www.youtube.com/watch?v=fE0P6H8eK4I "Dinámica de fluidos en tiempo real: CPU vs GPU" por Jesús Martín Berlanga
Resolver ecuaciones diferenciales parciales como la ecuación de Navier Stokes de dinámica de fluidos:
Ver también:
CPython Global Intepreter Lock (GIL)
Como un caso de estudio rápido, quiero señalar el Bloqueo de intérprete global de Python (GIL): ¿Qué es el bloqueo de intérprete global (GIL) en CPython?
Este detalle de implementación de CPython evita que varios subprocesos de Python utilicen eficientemente el trabajo vinculado a la CPU. Los documentos de CPython dicen:
Por lo tanto, aquí tenemos un ejemplo en el que el contenido vinculado a la CPU no es adecuado y el enlace de E / S sí.
fuente
El límite de CPU significa que la CPU o la unidad de procesamiento central bloquea el programa, mientras que el límite de E / S significa que el programa tiene un cuello de botella por E / S o entrada / salida, como leer o escribir en el disco, la red, etc.
En general, cuando se optimizan los programas informáticos, se intenta buscar el cuello de botella y eliminarlo. Saber que su programa está vinculado a la CPU ayuda, por lo que uno no optimiza innecesariamente otra cosa.
[Y por "cuello de botella", me refiero a lo que hace que su programa vaya más lento de lo que hubiera sido de otra manera].
fuente
Otra forma de expresar la misma idea:
Si acelerar la CPU no acelera su programa, puede estar vinculado a E / S.
Si acelerar la E / S (por ejemplo, usar un disco más rápido) no ayuda, su programa puede estar vinculado a la CPU.
(Solía "puede ser" porque necesita tener en cuenta otros recursos. La memoria es un ejemplo).
fuente
Cuando su programa está esperando E / S (es decir, una lectura / escritura de disco o lectura / escritura de red, etc.), la CPU es libre de realizar otras tareas incluso si su programa está detenido. La velocidad de su programa dependerá principalmente de qué tan rápido puede suceder IO, y si desea acelerarlo, deberá acelerar la E / S.
Si su programa ejecuta muchas instrucciones de programa y no espera E / S, se dice que está vinculado a la CPU. Acelerar la CPU hará que el programa se ejecute más rápido.
En cualquier caso, la clave para acelerar el programa podría no ser acelerar el hardware, sino optimizar el programa para reducir la cantidad de E / S o CPU que necesita, o hacer que haga E / S mientras también hace un uso intensivo de la CPU cosas.
fuente
El límite de E / S se refiere a una condición en la que el tiempo que lleva completar un cálculo está determinado principalmente por el período de espera para que se completen las operaciones de entrada / salida.
Esto es lo opuesto a una tarea vinculada a la CPU. Esta circunstancia surge cuando la velocidad a la que se solicitan los datos es más lenta que la velocidad que se consume o, en otras palabras, se pasa más tiempo solicitando datos que procesándolos.
fuente
Procesos vinculados a IO: pase más tiempo haciendo IO que los cálculos, tenga muchas ráfagas cortas de CPU. Procesos vinculados a la CPU: pase más tiempo haciendo cálculos, pocas ráfagas de CPU muy largas
fuente
Mira lo que dice Microsoft.
Ejemplo de enlace de E / S: descarga de datos de un servicio web
Ejemplo vinculado a la CPU: realizar un cálculo para un juego
fuente
Una aplicación está vinculada a la CPU cuando el rendimiento aritmético / lógico / de punto flotante (A / L / FP) durante la ejecución está mayormente cerca del rendimiento máximo teórico del procesador (datos proporcionados por el fabricante y determinados por las características del procesador: número de núcleos, frecuencia, registros, ALU, FPU, etc.).
Es muy difícil lograr el rendimiento máximo en aplicaciones del mundo real, por no decir imposible. La mayoría de las aplicaciones acceden a la memoria en diferentes partes de la ejecución y el procesador no realiza operaciones A / L / FP durante varios ciclos. Esto se llama limitación de von Neumann debido a la distancia que existe entre la memoria y el procesador.
Si desea estar cerca del rendimiento máximo de la CPU, una estrategia podría ser tratar de reutilizar la mayoría de los datos en la memoria caché para evitar requerir datos de la memoria principal. Un algoritmo que explota esta característica es la multiplicación matriz-matriz (si ambas matrices pueden almacenarse en la memoria caché). Esto sucede porque si las matrices son de tamaño,
n x n
entonces debe realizar2 n^3
operaciones utilizando solo2 n^2
números de datos FP. Por otro lado, la adición de matriz, por ejemplo, es una aplicación menos unida a la CPU o más unida a la memoria que la multiplicación de la matriz, ya que solo requieren^2
FLOP con los mismos datos.En la siguiente figura se muestran los FLOP obtenidos con algoritmos ingenuos para la suma de matrices y la multiplicación de matrices en un Intel i5-9300H:
Tenga en cuenta que, como se esperaba, el rendimiento de la multiplicación de la matriz es mayor que la suma de la matriz. Estos resultados se pueden reproducir ejecutando
test/gemm
ytest/matadd
disponibles en este repositorio .Sugiero también ver el video dado por J. Dongarra sobre este efecto.
fuente
Proceso vinculado de E / S: - Si la mayor parte de la vida útil de un proceso se pasa en estado de E / S, entonces el proceso es un proceso vinculado a E / S. Ejemplo: -calculador, explorador de Internet
Proceso vinculado a la CPU: - Si la mayor parte de la vida del proceso se gasta en la CPU, entonces es un proceso vinculado a la CPU.
fuente