Usted ve esta frase o similar de vez en cuando, generalmente refiriéndose a un programa que afirma que no fueron diseñados para aprovechar al máximo los procesadores multi-core. Esto es común especialmente con la programación de videojuegos. (por supuesto, muchos programas no tienen concurrencia y no la necesitan, como scripts básicos, etc.).
¿Cómo puede ser esto? Muchos programas (especialmente juegos) utilizan la concurrencia de forma inherente, y dado que el sistema operativo se encarga de la programación de tareas en la CPU, ¿estos programas no aprovechan inherentemente los múltiples núcleos disponibles? ¿Qué significaría en este contexto "aprovechar múltiples núcleos"? ¿Están estos desarrolladores realmente prohibiendo la programación de tareas del sistema operativo y forzando la afinidad o su propia programación? (Suena como un problema importante de estabilidad).
Soy un programador de Java, así que tal vez no he tenido que lidiar con esto debido a abstracciones o cosas por el estilo.
fuente
Respuestas:
La buena concurrencia requiere mucho más que lanzar algunos hilos en una aplicación y esperar lo mejor. Hay un rango en la concurrencia de un programa de vergonzosamente paralelo a secuencial pura. Cualquier programa puede usar la ley de Amdahl para expresar cuán escalable es un problema o algoritmo. Un par de calificaciones para una aplicación vergonzosamente paralela sería:
Hay otras calificaciones, pero con solo estas dos podemos entender por qué los juegos en particular no son tan fáciles como podría pensarse para aprovechar múltiples núcleos. Por un lado, el modelo del mundo que se representará debe compartirse ya que las diferentes funciones calculan la física, el movimiento, aplican inteligencia artificial, etc. Segundo, cada cuadro de este modelo de juego debe representarse en la pantalla con una tarjeta gráfica.
Para ser justos, muchos creadores de juegos usan motores de juegos producidos por terceros. Tomó un tiempo, pero estos motores de juegos de terceros ahora son mucho más paralelos de lo que solían ser.
Hay desafíos arquitectónicos más grandes al tratar con la concurrencia efectiva
La concurrencia puede tomar muchas formas, desde ejecutar tareas en segundo plano hasta un soporte arquitectónico completo para la concurrencia. Algunos idiomas le brindan características de concurrencia muy potentes, como ERLANG , pero requiere que piense de manera muy diferente sobre cómo construir su aplicación.
No todos los programas realmente necesitan la complejidad del soporte multinúcleo completo. Un ejemplo de esto es el software de impuestos, o cualquier aplicación basada en formularios. Cuando pasa la mayor parte de su tiempo esperando que el usuario haga algo, la complejidad de las aplicaciones multiproceso simplemente no es tan útil.
Algunas aplicaciones se prestan a una solución paralela más vergonzosa, como las aplicaciones web. En este caso, la plataforma comienza vergonzosamente paralela y depende de usted no tener que imponer contención de hilos.
La línea de fondo:
No todas las aplicaciones se ven realmente perjudicadas por no aprovechar múltiples hilos (y por lo tanto, núcleos). Para los que están afectados por eso, a veces los cálculos no son amigables con el procesamiento paralelo o la sobrecarga para coordinarlo haría que la aplicación sea más frágil. Desafortunadamente, el procesamiento paralelo todavía no es tan fácil como debería ser hacerlo bien.
fuente
No, en realidad es lo contrario. La mayoría de las aplicaciones están escritas en una mentalidad de subproceso único, y los desarrolladores nunca realizaron los cambios necesarios para admitir la concurrencia.
En C, C ++ y C #, debe indicar explícitamente a la aplicación que inicie nuevos subprocesos y / o procesos.
Creo que te estás enfocando demasiado en la programación de los hilos y no lo suficiente en el manejo de datos dentro de los hilos potenciales. Compartir datos a través de hilos y / o procesos requiere alguna forma de sincronización. Si cambia una aplicación para usar varios subprocesos pero no logra establecer esa sincronización, es probable que vea muchos errores difíciles de rastrear en el código.
Para las aplicaciones multiproceso en las que he trabajado, generalmente nunca me he preocupado por el envío y solo por la sincronización de datos. Las únicas veces que tuve que preocuparme por el envío fue cuando estaba persiguiendo condiciones de carrera debido a una sincronización de datos incorrecta.
En general, cuando una aplicación dice que no puede usar múltiples núcleos, significa que no tienen la sincronización para proteger la manipulación de datos.
fuente
Esto no se trata tanto de múltiples núcleos como de múltiples hilos. El sistema operativo puede programar un subproceso para que se ejecute en el núcleo que desee, y esta programación es transparente para el programa que se está programando. Sin embargo, muchos programas no se escriben utilizando múltiples hilos, por lo que solo pueden ejecutarse en un núcleo a la vez.
¿Por qué escribiría un programa de subproceso único? Son más fáciles de escribir y de depurar: una cosa sucede después de otra (en lugar de que sucedan varias cosas a la vez y es posible que se interpongan entre sí). O su programa puede no estar dirigido a máquinas de múltiples núcleos (como fue el caso con los juegos antiguos). En algunos casos, un programa de subprocesos múltiples podría incluso ejecutarse más lentamente que una versión de subprocesos simples si la sobrecarga de los conmutadores de contexto y la comunicación entre subprocesos supera la velocidad obtenida por la ejecución paralela (algunas partes del programa pueden no ser paralelizables).
fuente
Esta no es una respuesta completa. Es una historia de advertencia.
Un día pensé que les mostraría a los estudiantes en mi curso de programación concurrente una clasificación rápida paralela. Quicksort debería paralelizarse bien, pensé. Usé dos hilos. Lo ejecuté en mi computadora de un solo núcleo. Los resultados fueron:
Esto fue sobre lo que esperaba.
Luego lo probé en una nueva máquina de doble núcleo.
Los dos hilos compartieron una cola de tareas restantes. Parece que los campos del objeto de la cola se barajan de un lado a otro entre el caché de un núcleo y el del otro.
fuente