2011-06-17 23 views
24

Soy nuevo en este tipo de programación y necesito su punto de vista.Multithreading versus multiprocesamiento

Tengo que crear una aplicación, pero no puedo hacer que calcule lo suficientemente rápido. Ya he probado Intel TBB, y es fácil de usar, pero nunca he usado otras bibliotecas.

En la programación multiprocesador, estoy leyendo acerca de OpenMP y Boost para el multihilo, pero no conozco sus pros y sus contras.

En C++, ¿cuándo es la programación multiproceso ventajosa en comparación con la programación multiprocesador y viceversa? ¿Cuál es el más adecuado para cálculos pesados ​​o el inicio de muchas tareas ...? ¿Cuáles son sus ventajas y desventajas cuando construimos una aplicación diseñada con ellos? Y finalmente, ¿con qué biblioteca es mejor trabajar?

+1

En una máquina multiprocesador con una biblioteca de hilos como boost aprovechará los núcleos disponibles. También puede tener múltiples hilos en un procesador que se pueden intercalar con tecnologías como hyperthreading en Pentium 4. ¿Quiso decir multi-proceso y un sistema distribuido o multi-threading? Puede hacer ambas cosas en realidad, pero la naturaleza de los hilos es obtener paralelismo independientemente del procesador. FYI boost se basa en los hilos de posix hasta donde yo sé y me resulta bastante fácil de usar. Además, el nuevo estándar C++ 0x incluirá el soporte de subprocesos nativo del idioma. – AJG85

+0

¿Qué opinas sobre Boost e Intel TBB? Es más rápido que Intel TBB? ¿O debería buscar Intel si tengo un procesador Intel? – Nazka

+0

Intel TBB tiene la ventaja en algunas áreas donde proporciona primitivas paralelas optimizadas como bucles for-parales paralelos, etc., que ayudan en la creación de algoritmos de estilo de dispersión dispersa en paralelo en procesadores Intel, así como en otros cálculos paralelos. Boost Threads es principalmente un paquete de threads multiplataforma que se ejecutará en muchos tipos de hardware y plataformas de sistema operativo. Sin embargo, si necesita ciertas primitivas computacionales paralelas, Boost Threads no las proporciona directamente, tendría que codificarlas usted mismo. Entonces, podrías ver a TBB como a un nivel de abstracción más alto que Boost. – Jason

Respuesta

50

El multihebra significa exactamente eso, ejecuta múltiples hilos. Esto se puede hacer en un sistema de procesador único o en un sistema multiprocesador.

En un sistema de un solo procesador, cuando se ejecutan múltiples hilos, la observación real del equipo haciendo varias cosas a la vez (es decir, la multitarea) es una ilusión, ya que lo que realmente pasa en el fondo es que hay es un programador de software que realiza un corte de tiempo en una sola CPU. De modo que solo una única tarea está sucediendo en un momento determinado, pero el planificador cambia de tareas lo suficientemente rápido como para que nunca note que existen múltiples procesos, hilos, etc., compitiendo por el mismo recurso de CPU.

En un sistema multiprocesador, se reduce la necesidad de cortar el tiempo. El efecto de división de tiempo todavía está allí, porque un sistema operativo moderno podría tener cientos de subprocesos compitiendo por dos o más procesadores, y normalmente nunca hay una relación 1 a 1 en el número de subprocesos con la cantidad de núcleos de procesamiento disponibles. Entonces, en algún punto, un hilo tendrá que detenerse y se iniciará otro hilo en una CPU que los dos hilos están compartiendo. Esto es manejado nuevamente por el programador del sistema operativo. Dicho esto, con un sistema multiprocesador, puede tener dos cosas que suceden al mismo tiempo, a diferencia del sistema del procesador único.

Al final, los dos paradigmas son realmente algo ortogonales en el sentido de que necesitará multithreading siempre que quiera tener dos o más tareas ejecutándose de forma asincrónica, pero debido a la división en el tiempo, no necesariamente necesita un multi- sistema de procesador para lograr eso. Si intenta ejecutar varios subprocesos y está realizando una tarea que es muy paralela (es decir, intenta resolver una integral), entonces sí, cuantos más núcleos pueda arrojar a un problema, mejor. No necesariamente necesitará una relación de 1 a 1 entre subprocesos y núcleos de procesamiento, pero al mismo tiempo, no desea escindir tantos subprocesos que termine con toneladas de subprocesos inactivos porque deben esperar a programarse en uno de los núcleos de CPU disponibles. Por otro lado, si sus tareas paralelas requieren algún componente secuencial, es decir, un hilo estará esperando el resultado de otro hilo antes de que pueda continuar, entonces podrá ejecutar más hilos con algún tipo de barrera o método de sincronización para que los hilos que necesitan estar inactivos no están girando usando el tiempo de CPU, y solo los hilos que necesitan ejecutarse compiten por los recursos de la CPU.

+2

¡Dang, escribe rápido! Añadiré mis dos centavos como comentario. – AJG85

+0

Todo comentario es genial para mí :) @ Jason, por lo que hilo está diseñado para programar gran parte de la aplicación y hacer su trabajo no? – Nazka

+0

Un hilo se puede usar para una tarea ... esa tarea puede ser cualquier cosa. Podría ser algo que se ejecute durante toda la duración de su programa, como un daemon de red que "escucharía" las conexiones en un socket y luego generaría más hilos para administrar esas conexiones. Un hilo también se puede usar para una tarea pequeña, como resolver una iteración de una integral, que es una tarea altamente paralela. – Jason

2

Responde la primera pregunta: El mejor método es usar técnicas de subprocesamiento múltiple en el código hasta llegar al punto en que incluso eso no te da suficiente beneficio. Supongamos que el sistema operativo manejará la delegación a múltiples procesadores si están disponibles.

Si realmente está trabajando en un problema donde el multihilo no es suficiente, incluso con múltiples procesadores (o si está ejecutando un sistema operativo que no está utilizando sus múltiples procesadores), entonces puede preocuparse por descubrir cómo para obtener más poder. Lo que podría significar procesos de desove a través de una red a otras máquinas.

No he usado TBB, pero he usado IPP y he encontrado que es eficiente y está bien diseñado. Boost es portátil.

20

Hay algunos puntos importantes que creo que deberían agregarse a la excelente respuesta de @Jason.

Primero, el multihilo no siempre es una ilusión, incluso en un solo procesador: hay operaciones que no involucran el procesador. Se trata principalmente de E/S - disco, red, terminales, etc. La forma básica por dicha operación se bloqueo o sincrónica, es decir, el programa espera hasta que se complete la operación y luego procede. Mientras espera, la CPU cambia a otro proceso/subproceso.

si tiene algo que puede hacer durante ese tiempo (por ejemplo, el cálculo de fondo a la espera de la entrada del usuario, sirviendo otra solicitud, etc.) que tienen básicamente dos opciones:

  • uso E/S asíncrona : llama a sin bloqueo E/S proporcionándole una función de devolución de llamada , diciéndole "llamar a esta función cuando haya terminado". La llamada vuelve inmediatamente y la operación de E/S continúa en segundo plano. Sigues con las otras cosas.

  • utilizar multiprocesamiento: tiene un hilo dedicado para cada tipo de tarea. Mientras uno espera la llamada de E/S de bloqueo, la otra continúa.

Ambos enfoques son paradigmas de programación difíciles, cada uno tiene sus pros y sus contras.

  • con async I/O la lógica de la lógica del programa es menos obvia y es difícil de seguir y depurar. Sin embargo, evita problemas de seguridad de hilo.
  • con hilos, el desafío es escribir programas thread-safe. Las fallas de seguridad del subproceso son errores desagradables que son bastante difíciles de reproducir. El uso excesivo del bloqueo puede conducir a la degradación en lugar de mejorar el rendimiento.

(llegando a la multi-procesamiento)

multihilo hizo popular en Windows porque los procesos de manipulación es bastante pesado en Windows (la creación de un proceso, el contexto de conmutación, etc.) en lugar de hilos que son mucho más liviano (al menos este fue el caso cuando trabajé en Win2K).

En Linux/Unix, los procesos son mucho más ligeros. También los subprocesos (AFAIK) en Linux se implementan realmente como un tipo de procesos internos, por lo que no hay ganancia en el cambio de contexto de subprocesos frente a procesos. Sin embargo, debe usar alguna forma de IPC (comunicaciones entre procesos), como memoria compartida, tuberías, cola de mensajes, etc.

En una nota más ligera, mire el SQLite FAQ, que declara "¡Los hilos son malos"!:)

+2

También hay una tercera opción, multiplexar las E/S a través de select()/poll()/etc. Eso puede ser más seguro que el multihilo y más fácil de entender que la E/S asincrónica. –

0

Solo quería mencionar que el paradigma de Programación basada en flujo (http://www.jpaulmorrison.com/fbp) es un enfoque de multiprogramación/multiproceso natural para el desarrollo de aplicaciones. Proporciona una vista de aplicación consistente de alto nivel a bajo nivel. Las implementaciones de Java y C# aprovechan todos los procesadores en su máquina, pero la implementación anterior de C++ solo usa un procesador. Sin embargo, podría extenderse con bastante facilidad para usar BOOST (o pthreads, supongo) mediante el bloqueo de las conexiones. Empecé a convertirlo para usar fibras, pero no estoy seguro de si tiene sentido continuar en esta ruta. :-) Los comentarios serán apreciados. Por cierto, las implementaciones de Java y C# pueden incluso intercomunicarse usando sockets.