language-agnostic concurrency parallel-processing

language agnostic - ¿Cuál es la diferencia entre concurrencia y paralelismo?



language-agnostic concurrency (30)

¿Cuál es la diferencia entre concurrencia y paralelismo?

Se aprecian ejemplos.


La programación concurrente se refiere a las operaciones que parecen superponerse y está relacionada principalmente con la complejidad que surge debido al flujo de control no determinista. Los costos cuantitativos asociados con los programas concurrentes suelen ser tanto el rendimiento como la latencia. Los programas concurrentes a menudo están vinculados a IO pero no siempre, por ejemplo, los recolectores de basura concurrentes están completamente en la CPU. El ejemplo pedagógico de un programa concurrente es un rastreador web. Este programa inicia las solicitudes de páginas web y acepta las respuestas simultáneamente a medida que los resultados de las descargas están disponibles, acumulando un conjunto de páginas que ya se han visitado. El flujo de control no es determinista porque las respuestas no se reciben necesariamente en el mismo orden cada vez que se ejecuta el programa. Esta característica puede hacer que sea muy difícil depurar programas concurrentes.Algunas aplicaciones son fundamentalmente concurrentes, por ejemplo, los servidores web deben manejar las conexiones de los clientes al mismo tiempo. Erlang es quizás el lenguaje más prometedor para la programación altamente concurrente.

La programación paralela se refiere a operaciones que se superponen para el objetivo específico de mejorar el rendimiento. Las dificultades de la programación concurrente se evitan al hacer que el flujo de control sea determinista. Normalmente, los programas generan conjuntos de tareas secundarias que se ejecutan en paralelo y la tarea principal solo continúa una vez que cada subtarea ha terminado. Esto hace que los programas paralelos sean mucho más fáciles de depurar. La parte difícil de la programación paralela es la optimización del rendimiento con respecto a cuestiones como la granularidad y la comunicación. Este último sigue siendo un problema en el contexto de los multinúcleos porque hay un costo considerable asociado con la transferencia de datos de un caché a otro. La matriz matricial densa multiplica es un ejemplo pedagógico de programación paralela y se puede resolver de manera eficiente usando Straasen ''s divide y conquista el algoritmo y ataca los sub-problemas en paralelo. Cilk es quizás el lenguaje más prometedor para la programación paralela de alto rendimiento en computadoras con memoria compartida (incluidos los multinúcleos).

Copiado de mi respuesta: https://.com/a/3982782


Por qué existe la confusión

La confusión existe porque los significados del diccionario de estas dos palabras son casi los mismos:

  • Concurrente : existente, sucede o se hace al mismo tiempo (dictionary.com)
  • Paralela : muy similar y suele suceder al mismo tiempo (merriam webster).

Sin embargo, la forma en que se utilizan en la informática y la programación son muy diferentes. Aquí está mi interpretación:

  • Concurrencia : Interrumpibilidad
  • Paralelismo : independencia

Entonces, ¿qué quiero decir con las definiciones anteriores?

Voy a aclarar con una analogía del mundo real. Digamos que tienes que hacer 2 tareas muy importantes en un día:

  1. Consigue un pasaporte
  2. Obtener una presentación hecha

Ahora, el problema es que la tarea 1 requiere que usted vaya a una oficina gubernamental extremadamente burocrática que lo hace esperar 4 horas seguidas para obtener su pasaporte. Mientras tanto, la tarea 2 es requerida por su oficina, y es una tarea crítica. Ambos deben ser terminados en un día específico.

Caso 1: Ejecución secuencial

Por lo general, usted conducirá a la oficina de pasaportes durante 2 horas, esperará en la fila durante 4 horas, hará la tarea, regresará dos horas, irá a su casa, se mantendrá alejado 5 horas más y terminará la presentación.

Caso 2: Ejecución concurrente

Pero eres inteligente. Usted planea con antelación. Lleva consigo una computadora portátil y, mientras espera en la fila, comienza a trabajar en su presentación. De esta manera, una vez que regreses a casa, solo necesitas trabajar 1 hora extra en lugar de 5.

En este caso, ambas tareas las realiza usted, solo en piezas. Interrumpió la tarea de pasaporte mientras esperaba en la fila y trabajó en la presentación. Cuando llamaron a su número, interrumpió la tarea de presentación y cambió a la tarea de pasaporte. El ahorro en el tiempo fue esencialmente posible debido a la capacidad de interrupción de ambas tareas.

La concurrencia, IMO, debe tomarse como "aislamiento" en las propiedades ACID de una base de datos. Dos transacciones de la base de datos satisfacen el requisito de aislamiento si realiza transacciones secundarias en cada una de las formas intercaladas y el resultado final es el mismo que si las dos tareas se realizaran en serie. Recuerde que para el pasaporte y las tareas de presentación, usted es el único ejecutor .

Caso 3: Ejecución paralela

Ahora, ya que eres un tipo tan inteligente, obviamente eres superior, y tienes un asistente. Entonces, antes de salir para comenzar la tarea de pasaporte, lo llama y le dice que prepare el primer borrador de la presentación. Pasas todo el día y terminas la tarea de pasaporte, regresas y ves tus correos, y encuentras el borrador de la presentación. Él ha hecho un trabajo bastante sólido y con algunas ediciones en 2 horas más, lo finalizas.

Ahora, ya que su asistente es tan inteligente como usted, pudo trabajar en él de manera independiente , sin necesidad de pedirle constantemente aclaraciones. Por lo tanto, debido a la independencia de las tareas, se llevaron a cabo al mismo tiempo por dos ejecutores diferentes .

¿Aún conmigo? Bien...

Caso 4: concurrente pero no paralelo

¿Recuerdas tu tarea de pasaporte, donde tienes que esperar en la fila? Ya que es su pasaporte, su asistente no puede esperar en la fila por usted. Por lo tanto, la tarea de pasaporte tiene interrupibilidad (puede detenerla mientras espera en la línea y reanudarla más tarde cuando se llama su número), pero no tiene independencia (su asistente no puede esperar en su lugar).

Caso 5: paralelo pero no concurrente

Supongamos que la oficina del gobierno tiene un control de seguridad para entrar a las instalaciones. Aquí, debe eliminar todos los dispositivos electrónicos y enviarlos a los oficiales, y solo devolverán sus dispositivos después de completar su tarea.

En este caso, la tarea de pasaporte no es independiente ni interrumpible . Incluso si está esperando en la línea, no puede trabajar en otra cosa porque no tiene el equipo necesario.

Del mismo modo, digamos que la presentación es tan altamente matemática que requiere una concentración del 100% durante al menos 5 horas. No puede hacerlo mientras espera en la fila para la tarea de pasaporte, incluso si tiene su computadora portátil con usted.

En este caso, la tarea de presentación es independiente (usted o su asistente pueden dedicar 5 horas de esfuerzo enfocado), pero no es interrumpible .

Caso 6: Ejecución concurrente y paralela

Ahora, diga que además de asignar a su asistente a la presentación, también lleva consigo una computadora portátil para la tarea de pasaporte. Mientras espera en la línea, verá que su asistente ha creado las primeras 10 diapositivas en una plataforma compartida. Envias comentarios sobre su trabajo con algunas correcciones. Más tarde, cuando llegue a casa, en lugar de 2 horas para finalizar el borrador, solo necesita 15 minutos.

Esto fue posible porque la tarea de presentación tiene independencia (cualquiera de ustedes puede hacerlo) e interrupibilidad (puede detenerla y reanudarla más tarde). Así que ejecutó simultáneamente ambas tareas y ejecutó la tarea de presentación en paralelo.

Digamos que, además de ser demasiado burocrático, la oficina del gobierno es corrupta. Por lo tanto, puede mostrar su identificación, ingresarla, comenzar a esperar en la cola para llamar a su número, sobornar a un guardia y a otra persona para mantener su posición en la línea, escapar, regresar antes de llamar a su número y reanudar la espera tú mismo.

En este caso, puede realizar las tareas de pasaporte y presentación al mismo tiempo y en paralelo. Puedes escabullirte, y tu asistente es quien mantiene tu posición. Ambos pueden trabajar en la presentación, etc.

Volver a Ciencias de la Computación

En el mundo de la computación, aquí hay ejemplos de escenarios típicos de cada uno de estos casos:

  • Caso 1: Procesamiento de interrupciones.
  • Caso 2: cuando solo hay un procesador, pero todas las tareas en ejecución tienen tiempos de espera debido a la E / S.
  • Caso 3: a menudo se ve cuando se trata de grupos de map-reduce o hadoop.
  • Caso 4: Creo que el caso 4 es raro. Es poco común que una tarea sea concurrente pero no paralela. Pero podría suceder. Por ejemplo, suponga que su tarea requiere acceso a un chip de cómputo especial al que solo se puede acceder a través del procesador-1. Por lo tanto, incluso si el procesador-2 está libre y el procesador-1 está realizando otra tarea, la tarea de cálculo especial no puede continuar en el procesador-2.
  • Caso 5: también raro, pero no tan raro como el Caso 4. Un código no concurrente puede ser una región crítica protegida por mutexes. Una vez que se inicia, debe ejecutarse hasta su finalización. Sin embargo, dos regiones críticas diferentes pueden progresar simultáneamente en dos procesadores diferentes.
  • Caso 6: OMI, la mayoría de las discusiones sobre programación paralela o concurrente se refieren básicamente al Caso 6. Esta es una combinación y una combinación de ejecuciones paralelas y simultáneas.

Concurrencia y go

Si ve por qué Rob Pike está diciendo que la concurrencia es mejor, tiene que entender que la razón es. Tiene una tarea realmente larga en la que hay varios períodos de espera en los que espera algunas operaciones externas, como la lectura de archivos y la descarga de la red. En su conferencia, todo lo que dice es, "simplemente rompa esta larga tarea secuencial para que pueda hacer algo útil mientras espera". Es por eso que habla de diferentes organizaciones con diversos geófonos.

Ahora la fuerza de Go proviene de hacer que esta ruptura sea realmente fácil con la palabra clave y los canales de go . Además, hay un excelente soporte subyacente en el tiempo de ejecución para programar estos goroutines.

Pero esencialmente, ¿es mejor la concurrencia que el paralelismo?

¿Son las manzanas preferidas más que las naranjas?


Concurrencia: múltiples flujos de ejecución con el potencial de compartir recursos.

Ej: dos hilos que compiten por un puerto de E / S.

paralelismo: dividir un problema en múltiples partes similares.

Ej: analizar un archivo grande ejecutando dos procesos en cada mitad del archivo.


Digamos que tienes un programa que tiene dos hilos. El programa puede ejecutarse de dos maneras:

Concurrency Concurrency + parallelism (Single-Core CPU) (Multi-Core CPU) ___ ___ ___ |th1| |th1|th2| | | | |___| |___|___ | |___ |th2| |___|th2| ___|___| ___|___| |th1| |th1| |___|___ | |___ |th2| | |th2|

En ambos casos, tenemos concurrencia por el simple hecho de que tenemos más de un hilo en ejecución.

Si ejecutamos este programa en una computadora con un solo núcleo de CPU, el sistema operativo estaría cambiando entre los dos subprocesos, permitiendo que un subproceso se ejecute a la vez.

Si ejecutáramos este programa en una computadora con una CPU de varios núcleos, podríamos ejecutar los dos subprocesos en paralelo , lado a lado al mismo tiempo.


Ejemplo simple:

Concurrente es: "Dos colas que acceden a un cajero automático"

Paralelo es: "Dos colas y dos cajeros automáticos"


En electrónica, serie y paralelo representan un tipo de topología estática, que determina el comportamiento real del circuito. Cuando no hay concurrencia, el paralelismo es determinista .

Para describir los fenómenos dinámicos relacionados con el tiempo , utilizamos los términos secuencial y concurrente . Por ejemplo, un cierto resultado puede obtenerse mediante una determinada secuencia de tareas (por ejemplo, una receta). Cuando estamos hablando con alguien, estamos produciendo una secuencia de palabras. Sin embargo, en realidad, muchos otros procesos ocurren en el mismo momento, y por lo tanto, concurren al resultado real de una determinada acción. Si mucha gente habla al mismo tiempo, las conversaciones concurrentes pueden interferir con nuestra secuencia, pero los resultados de esta interferencia no se conocen de antemano. La concurrencia introduce indeterminación .

La caracterización serial / paralela y secuencial / concurrente son ortogonales. Un ejemplo de esto está en la comunicación digital. En un adaptador en serie , un mensaje digital se distribuye temporalmente (es decir, secuencialmente ) a lo largo de la misma línea de comunicación (por ejemplo, un cable). En un adaptador paralelo , esto se divide también en líneas de comunicación paralelas (por ejemplo, muchos cables) y luego se reconstruye en el extremo receptor.

Imaginemos un juego, con 9 niños. Si los desechamos como una cadena, damos un mensaje al principio y lo recibimos al final, tendríamos una comunicación en serie. Más palabras componen el mensaje, que consiste en una secuencia de unidades de comunicación.

I like ice-cream so much. > X > X > X > X > X > X > X > X > X > ....

Este es un proceso secuencial reproducido en una infraestructura serial .

Ahora, imaginemos dividir a los niños en grupos de 3. Dividimos la frase en tres partes, damos el primero al niño de la línea a nuestra izquierda, el segundo al niño de la línea central, etc.

I like ice-cream so much. > I like > X > X > X > .... > .... > ice-cream > X > X > X > .... > so much > X > X > X > ....

Este es un proceso secuencial reproducido en una infraestructura paralela (aunque todavía está parcialmente serializado).

En ambos casos, suponiendo que haya una comunicación perfecta entre los niños, el resultado se determina de antemano.

Si hay otras personas que hablan con el primer hijo al mismo tiempo que usted, entonces tendremos procesos concurrentes . No sabemos qué proceso será considerado por la infraestructura, por lo que el resultado final no está determinado de antemano.


Imagina aprender un nuevo lenguaje de programación viendo un video tutorial. Debe pausar el video, aplicar lo que se dijo en el código y luego continuar viendo. Eso es concurrencia.

Ahora eres un programador profesional. Y te gusta escuchar música tranquila mientras codificas. Eso es paralelismo.

Disfrutar.


La concurrencia es la forma generalizada de paralelismo. Por ejemplo, el programa paralelo también se puede llamar concurrente, pero lo contrario no es cierto.

  1. La ejecución simultánea es posible en un solo procesador (varios subprocesos, administrados por el planificador o conjunto de subprocesos)

  2. La ejecución paralela no es posible en un solo procesador sino en múltiples procesadores. (Un proceso por procesador)

  3. La computación distribuida también es un tema relacionado y también puede llamarse computación concurrente, pero revertir no es cierto, como el paralelismo.

Para más detalles, lea este artículo de investigación Conceptos de programación concurrente.


Me gusta la charla de Rob Pike: la concurrencia no es paralelismo (¡es mejor!) (slides) (talk)

¡Rob suele hablar de Go y, por lo general, aborda la cuestión de concurrencia frente a paralelismo en una explicación visual e intuitiva! Aquí hay un breve resumen:

Tarea: ¡Vamos a quemar un montón de manuales de idiomas obsoletos! ¡Uno a la vez!

Concurrencia: ¡ Hay muchas descomposiciones concurrentes de la tarea! Un ejemplo:

Paralelismo: la configuración anterior se produce en paralelo si hay al menos 2 geófonos trabajando al mismo tiempo o no.


Para agregar a lo que otros han dicho:

La concurrencia es como tener un malabarista haciendo malabares con muchas bolas. Independientemente de cómo se vea, el malabarista solo atrapa / lanza una pelota por mano a la vez. El paralelismo es tener malabaristas múltiples que hacen malabares con pelotas simultáneamente.


Piense en ello como colas de servicio donde el servidor solo puede servir el primer trabajo en una cola.

1 servidor, 1 cola de trabajos (con 5 trabajos) -> sin concurrencia, sin paralelismo (solo un trabajo está siendo reparado hasta su finalización, el siguiente trabajo en la cola tiene que esperar hasta que se realice el trabajo revisado y no haya otro servidor para servicio

1 servidor, 2 o más colas diferentes (con 5 trabajos por cola) -> concurrencia (ya que el servidor comparte el tiempo con todos los primeros trabajos en colas, igual o ponderado), aún no hay paralelismo ya que en cualquier momento, hay uno y solo trabajo siendo atendido.

2 o más servidores, una Cola -> paralelismo (2 trabajos realizados en el mismo instante) pero sin concurrencia (el servidor no comparte tiempo, el tercer trabajo tiene que esperar hasta que uno de los servidores se complete).

2 o más servidores, 2 o más colas diferentes -> concurrencia y paralelismo

En otras palabras, la concurrencia es el tiempo compartido para completar un trabajo, PUEDE tardar el mismo tiempo en completar su trabajo, pero al menos comienza temprano. Lo importante es que los trabajos se pueden dividir en trabajos más pequeños, lo que permite el intercalado.

El paralelismo se logra con solo más CPU, servidores, personas, etc. que se ejecutan en paralelo.

Tenga en cuenta que, si se comparten los recursos, no se puede lograr un paralelismo puro, pero es aquí donde la concurrencia tendría su mejor uso práctico, ocupando otro trabajo que no necesita ese recurso.


Realmente me gustó esta representación gráfica de otra respuesta: creo que responde a la pregunta mucho mejor que muchas de las respuestas anteriores.

Paralelismo vs concurrencia Cuando dos subprocesos se ejecutan en paralelo, ambos se ejecutan al mismo tiempo. Por ejemplo, si tenemos dos subprocesos, A y B, entonces su ejecución paralela se vería así:

CPU 1: A ------------------------->

CPU 2: B ------------------------->

Cuando dos subprocesos se ejecutan simultáneamente, su ejecución se superpone. La superposición puede ocurrir de una de las dos formas siguientes: o los subprocesos se ejecutan al mismo tiempo (es decir, en paralelo, como anteriormente), o sus ejecuciones se están entrelazando en el procesador, de esta manera:

CPU 1: A -----------> B ----------> A -----------> B -------- ->

Por lo tanto, para nuestros propósitos, el paralelismo puede considerarse como un caso especial de concurrencia

Fuente: Otra respuesta aquí.

Espero que ayude.


Realmente me gusta la answer Paul Butcher a esta pregunta (él es el autor de Siete modelos de concurrencia en siete semanas ):

Aunque a menudo se confunden, el paralelismo y la concurrencia son cosas diferentes. La concurrencia es un aspecto del dominio del problema: su código debe manejar múltiples eventos simultáneos (o casi simultáneos) . El paralelismo, por el contrario, es un aspecto del dominio de la solución: desea que su programa se ejecute más rápido procesando diferentes partes del problema en paralelo. Algunos enfoques son aplicables a la concurrencia, otros al paralelismo y otros a ambos. Comprenda con qué se enfrenta y elija la herramienta adecuada para el trabajo.


Resuelven diferentes problemas. La concurrencia resuelve el problema de tener recursos de CPU escasos y muchas tareas. Entonces, creas hilos o rutas de ejecución independientes a través del código para compartir el tiempo en el recurso escaso. Hasta hace poco, la concurrencia ha dominado la discusión debido a la disponibilidad de la CPU.

El paralelismo resuelve el problema de encontrar suficientes tareas y tareas apropiadas (las que se pueden dividir correctamente) y distribuirlas sobre abundantes recursos de CPU. El paralelismo siempre ha existido, por supuesto, pero está llegando a la vanguardia porque los procesadores de múltiples núcleos son muy baratos.


Trataré de explicar con un ejemplo interesante y fácil de entender. :)

Supongamos que una organización organiza un torneo de ajedrez en el que 10 jugadores ( con las mismas habilidades para jugar al ajedrez ) desafiarán a un campeón profesional de ajedrez. Y dado que el ajedrez es un juego 1: 1, los organizadores deben realizar 10 juegos de manera eficiente en el tiempo para que puedan terminar todo el evento lo más rápido posible.

Esperamos que los siguientes escenarios describan fácilmente varias formas de llevar a cabo estos 10 juegos:

1) SERIE : digamos que el profesional juega con cada persona una por una, es decir, comienza y termina el juego con una persona y luego comienza el siguiente juego con la siguiente persona y así sucesivamente. En otras palabras, decidieron conducir los juegos de forma secuencial. Entonces, si un juego tarda 10 minutos en completarse, 10 juegos tomarán 100 minutos, también se supone que la transición de un juego a otro tarda 6 segundos y luego, durante 10 juegos, será de 54 segundos (aproximadamente 1 minuto).

por lo que todo el evento se completará aproximadamente en 101 minutos ( PEOR ENFOQUE )

2) CONCURRENTE : digamos que el profesional juega su turno y pasa al siguiente jugador, así que los 10 jugadores juegan simultáneamente, pero el jugador profesional no es con dos personas a la vez, juega su turno y pasa a la siguiente persona. Ahora suponga que el jugador profesional tarda 6 segundos en jugar su turno y también el tiempo de transición del jugador profesional b / w dos jugadores es de 6 segundos, por lo que el tiempo total de transición para regresar al primer jugador será de 1 minuto (10x6 segundos). Por lo tanto, cuando vuelve a ser la primera persona con la que se inició el evento, han pasado 2 minutos (10xtime_per_turn_by_champion + 10xtransition_time = 2mins)

Suponiendo que todos los jugadores tomen 45 segundos para completar su turno, entonces se basan en 10 minutos por juego del evento SERIAL el no. de rondas antes de que termine el juego, 600 / (45 + 6) = 11 rondas (aprox.)

Así que todo el evento se completará aproximadamente en 11xtime_per_turn_by_player _ & _ champion + 11xtransition_time_across_10_players = 11x51 + 11x60sec = 561 + 660 = 1221sec = 20.35mins (aproximadamente)

VER LA MEJORA de 101 minutos a 20.35 minutos ( MEJOR ENFOQUE )

3) PARALELO : digamos que los organizadores obtienen algunos fondos adicionales y, por lo tanto, decidieron invitar a dos jugadores campeones profesionales (ambos igualmente capaces) y dividieron el conjunto de los mismos 10 jugadores (aspirantes) en dos grupos de 5 cada uno y los asignaron a dos campeones, es decir, uno grupo de cada uno. Ahora el evento está progresando en paralelo en estos dos conjuntos, es decir, al menos dos jugadores (uno en cada grupo) están jugando contra los dos jugadores profesionales en su grupo respectivo.

Sin embargo, dentro del grupo, el jugador profesional con un jugador a la vez (es decir, secuencialmente) así que sin ningún cálculo, puede deducir fácilmente que todo el evento se completará aproximadamente en 101/2 = 50.5 minutos para completar

VER LA MEJORA de 101 minutos a 50.5 minutos ( BUEN ENFOQUE )

4) CONCURRENTE + PARALELO : en el escenario anterior, digamos que los dos jugadores campeones jugarán simultáneamente (leerá el segundo punto) con los 5 jugadores en sus respectivos grupos, por lo que ahora los juegos de todos los grupos se ejecutan en paralelo pero dentro del grupo se ejecutan de manera simultánea.

Así que los juegos en un grupo se completarán aproximadamente en 11xtime_per_turn_by_player _ & _ champion + 11xtransition_time_across_5_players = 11x51 + 11x30 = 600 + 330 = 930sec = 15.5mins (aproximadamente)

Por lo tanto, todo el evento (con dos grupos paralelos de este tipo) se completará aproximadamente en 15.5 minutos.

VEA LA MEJORA de 101 minutos a 15.5 minutos ( MEJOR ENFOQUE )

NOTA: en el escenario anterior, si reemplaza a 10 jugadores con 10 trabajos similares y dos jugadores profesionales con dos núcleos de CPU, el siguiente ordenamiento seguirá siendo verdadero:

SERIE> PARALELO> CONCURRENTE> CONCURRENTE + PARALELO

(NOTA: este orden puede cambiar para otros escenarios, ya que este pedido depende en gran medida de la interdependencia de los trabajos, las necesidades de comunicación en b / w y la sobrecarga de transición en b / w)


Voy a ofrecer una respuesta que está en conflicto un poco con algunas de las respuestas populares aquí. En mi opinión, concurrencia es un término general que incluye paralelismo. La concurrencia se aplica a cualquier situación en la que las tareas o unidades de trabajo distintas se superponen en el tiempo. El paralelismo se aplica más específicamente a situaciones donde se evalúan / ejecutan distintas unidades de trabajo al mismo tiempo físico. La razón de ser del paralelismo es acelerar el software que puede beneficiarse de múltiples recursos de cómputo físico. El otro concepto importante que se ajusta a la concurrencia es la interactividad. La interactividad se aplica cuando la superposición de tareas es observable desde el mundo exterior. La razón de ser de la interactividad es crear un software que responda a entidades del mundo real como usuarios, pares de la red, periféricos de hardware, etc.

El paralelismo y la interactividad son dimensiones casi totalmente independientes de la concurrencia. Para un proyecto en particular, los desarrolladores pueden preocuparse por uno o por otro. Tienden a confundirse, entre otras cosas porque la abominación que son los hilos proporciona una primitiva razonablemente conveniente para hacer ambas cosas.

Un poco más de detalle sobre el paralelismo :

El paralelismo existe a escalas muy pequeñas (por ejemplo, paralelismo a nivel de instrucción en procesadores), escalas medias (por ejemplo, procesadores multinúcleo) y escalas grandes (por ejemplo, clústeres de computación de alto rendimiento). La presión sobre los desarrolladores de software para exponer más paralelismo a nivel de subprocesos ha aumentado en los últimos años, debido al crecimiento de los procesadores multinúcleo. El paralelismo está íntimamente conectado con la noción de dependencia . Las dependencias limitan la medida en que se puede lograr el paralelismo; dos tareas no se pueden ejecutar en paralelo si una depende de la otra (ignorando la especulación).

Hay muchos patrones y marcos que los programadores utilizan para expresar el paralelismo: tuberías, grupos de tareas, operaciones agregadas en estructuras de datos ("arreglos paralelos").

Un poco más de detalle sobre la interactividad :

La forma más básica y común de hacer interactividad es con eventos (es decir, un bucle de eventos y manejadores / devoluciones de llamada). Para tareas simples los eventos son geniales. Intentar realizar tareas más complejas con eventos se convierte en extracción de pila (también conocido como infierno de devolución de llamada; también conocido como inversión de control). Cuando te hartas de los eventos, puedes probar cosas más exóticas como generadores, coroutines (también conocidos como Async / Await) o ​​hilos cooperativos.

Por el amor al software confiable, no uses hilos si lo que buscas es interactividad.

Curmudgeonliness

No me gusta la "concurrencia de Rob Pike no es el paralelismo, es el mejor eslogan". La concurrencia no es mejor ni peor que el paralelismo. La concurrencia incluye interactividad que no se puede comparar de una manera mejor / peor con el paralelismo. Es como decir "el flujo de control es mejor que los datos".


(Estoy bastante sorprendido de que una pregunta tan fundamental no se resuelva correctamente y con precisión durante años ...)

En resumen, tanto la concurrencia como el paralelismo son propiedades de la computación .

A partir de la diferencia, aquí está la explicación de Robert Harper :

Lo primero que hay que entender es que el paralelismo no tiene nada que ver con la concurrencia . La concurrencia se refiere a la composición no determinista de los programas (o sus componentes). El paralelismo se ocupa de la eficiencia asintótica de los programas con comportamiento determinista . La concurrencia tiene que ver con la gestión de lo inmanejable: los eventos llegan por razones que escapan a nuestro control y debemos responder a ellos. Un usuario hace clic en el mouse, el administrador de ventanas debe responder, aunque la pantalla esté demandando atención. Tales situaciones son intrínsecamente no deterministas, pero también empleamos pro formaNo determinismo en un entorno determinista al pretender que los componentes señalizan los eventos en un orden arbitrario, y que debemos responder a ellos a medida que surjan. La composición no determinista es una poderosa idea de estructuración de programas. El paralelismo, por otro lado, tiene que ver con las dependencias entre las subcomputaciones de una computación determinista. El resultado no está en duda, pero hay muchos medios para lograrlo, algunos más eficientes que otros. Deseamos aprovechar esas oportunidades para nuestro beneficio.

Pueden ser tipos de propiedades ortogonales en los programas. Lea s1l3n0.blogspot.com/2013/04/… para ilustraciones adicionales. Y este discutió un poco más sobre la diferencia acerca de los componentes en la programación , como hilos.

Tenga en cuenta que los subprocesos o la multitarea son implementaciones de computación que sirven para propósitos más concretos. Pueden estar relacionados con el paralelismo y la concurrencia, pero no de una manera esencial. Por lo tanto, no son buenas entradas para comenzar la explicación.

Un punto culminante más: el "tiempo" (físico) no tiene casi nada que ver con las propiedades que se analizan aquí. El tiempo es solo una forma de implementación de la medición para mostrar el significado de las propiedades, pero lejos de la esencia. Piense dos veces el papel del "tiempo" en la complejidad del tiempo , que es más o menos similar, incluso la medición suele ser más significativa en ese caso.


Concurrencia: si un solo procesador resuelve dos o más problemas.

Paralelismo: Si un problema es resuelto por múltiples procesadores.


Concurrencia => Cuando se realizan múltiples tareas en períodos de tiempo superpuestos con recursos compartidos (potencialmente maximizando la utilización de los recursos).

Paralelo => cuando la tarea individual se divide en múltiples subtareas independientes simples que se pueden realizar simultáneamente.


El paralelismo es la ejecución simultánea de procesos en multiple cores per CPU o multiple CPUs (on a single motherboard) .

La concurrencia se produce cuando el paralelismo se logra en una single core CPU un single core CPU mediante el uso de algoritmos de programación que dividen el tiempo de la CPU (intervalo de tiempo). Los procesos están intercalados .

Unidades:

  • 1 o muchos núcleos en una CPU (casi todos los procesadores modernos)
  • 1 o muchas CPU en una placa base (piense en servidores de la vieja escuela)
  • 1 programa puede tener 1 o muchos hilos de ejecución.
  • 1 proceso puede tener 1 o muchos subprocesos de 1 programa (por ejemplo, para la ejecución de la serie Fibonacci para un número muy grande)
  • 1 programa puede tener 1 o muchos procesos (creo que cada ventana del navegador Chrome es un proceso)
  • 1 proceso es thread(s)+allocated memory by OS (montón, registros, pila, memoria de clase)

La concurrencia es cuando dos o más tareas pueden iniciarse, ejecutarse y completarse en períodos de tiempo superpuestos. No significa necesariamente que ambos se ejecutarán en el mismo instante. Por ejemplo, la multitarea en una máquina de un solo núcleo.

El paralelismo es cuando las tareas se ejecutan literalmente al mismo tiempo, por ejemplo, en un procesador multinúcleo.

Citando la guía de programación multiproceso de Sun :

  • Concurrencia: una condición que existe cuando al menos dos subprocesos están progresando. Una forma más generalizada de paralelismo que puede incluir la división del tiempo como una forma de paralelismo virtual.

  • Paralelismo: una condición que surge cuando al menos dos subprocesos se ejecutan simultáneamente.


La concurrencia puede implicar que las tareas se ejecuten simultáneamente o no (de hecho, se pueden ejecutar en procesadores / núcleos separados, pero también se pueden ejecutar en "tics"). Lo importante es que la concurrencia siempre se refiere a hacer una parte de una tarea mayor . Así que básicamente es una parte de algunos cálculos. Debe ser inteligente con respecto a lo que puede hacer simultáneamente y lo que no debe hacer y cómo sincronizar.

El paralelismo significa que estás haciendo algunas cosas simultáneamente. No necesitan ser parte de resolver un problema. Sus hilos pueden, por ejemplo, resolver un solo problema cada uno. Por supuesto, también se aplica la sincronización, pero desde una perspectiva diferente.


Paralelismo: tener múltiples hilos realiza tareas similares que son independientes entre sí en términos de datos y recursos que requieren para hacerlo. Por ejemplo: el rastreador de Google puede generar miles de subprocesos y cada subproceso puede hacer su tarea de forma independiente.

Concurrencia: la concurrencia entra en escena cuando se comparten datos, recursos compartidos entre los subprocesos. En un sistema transaccional, esto significa que tiene que sincronizar la sección crítica del código usando algunas técnicas como Bloqueos, semáforos, etc.


La ejecución de programación concurrente tiene 2 tipos: programación concurrente no paralela y programación concurrente paralela (también conocida como paralelismo).

La diferencia clave es que para el ojo humano, los hilos en una concurrencia no paralela parecen correr al mismo tiempo, pero en realidad no lo hacen. En los hilos de concurrencia no paralelos, se cambian rápidamente y se turnan para usar el procesador a través del tiempo. Mientras que en el paralelismo hay varios procesadores disponibles, varios subprocesos pueden ejecutarse en diferentes procesadores al mismo tiempo.

Referencia: Introducción a la concurrencia en lenguajes de programación.


"Concurrencia" es cuando hay varias cosas en progreso .

"Paralelismo" es cuando las cosas concurrentes están progresando al mismo tiempo .

Ejemplos de concurrencia sin paralelismo:

  • Múltiples hilos en un solo núcleo.
  • Múltiples mensajes en una cola de mensajes Win32.
  • Múltiples SqlDataReaders en una conexión MARS .
  • Múltiples promises JavaScript en una pestaña del navegador.

Sin embargo, tenga en cuenta que la diferencia entre concurrencia y paralelismo es a menudo una cuestión de perspectiva. Los ejemplos anteriores no son paralelos desde la perspectiva de (efectos observables de) la ejecución de su código. Pero hay un paralelismo a nivel de instrucción incluso dentro de un solo núcleo. Hay piezas de hardware que hacen cosas en paralelo con la CPU y luego interrumpen la CPU cuando terminan. La GPU podría estar en la pantalla mientras se está ejecutando el procedimiento de la ventana o el controlador de eventos. El DBMS podría estar atravesando B-Trees para la próxima consulta mientras aún está obteniendo los resultados de la anterior. El navegador podría estar haciendo diseño o en red mientras Promise.resolve()se está ejecutando. Etcétera etcétera...

Ahí vas. El mundo está tan desordenado como siempre;)


Genial, déjame tomar un escenario para mostrar lo que entiendo. Supongamos que hay 3 niños llamados: A, B, C. A y B hablan, C escuchan. Para A y B, son paralelos: A: Yo soy A. B: Yo soy B.

Pero para C, su cerebro debe tomar el proceso concurrente para escuchar A y B, quizás: Soy IA soy B.


La concurrencia simple significa que se ejecutan más de una tarea (no es necesario en paralelo). Por ejemplo, supongamos que tenemos 3 tareas en cualquier momento: más de una puede estar ejecutándose o todas pueden estar ejecutándose al mismo tiempo.

El paralelismo significa que están literalmente corriendo en paralelo. Así que en ese caso los tres deben estar corriendo al mismo tiempo.


La explicación de esta fuente fue útil para mí:

La concurrencia está relacionada con la forma en que una aplicación maneja múltiples tareas en las que trabaja. Una aplicación puede procesar una tarea a la vez (secuencialmente) o trabajar en varias tareas al mismo tiempo (simultáneamente).

Por otro lado, el paralelismo está relacionado con cómo una aplicación maneja cada tarea individual. Una aplicación puede procesar la tarea en serie de principio a fin, o dividir la tarea en subtareas que se pueden completar en paralelo.

Como puede ver, una aplicación puede ser concurrente, pero no paralela. Esto significa que procesa más de una tarea al mismo tiempo, pero las tareas no se dividen en subtareas.

Una aplicación también puede ser paralela pero no concurrente. Esto significa que la aplicación solo funciona en una tarea a la vez, y esta tarea se divide en subtareas que se pueden procesar en paralelo.

Adicionalmente, una aplicación no puede ser concurrente ni paralela. Esto significa que funciona en una sola tarea a la vez, y la tarea nunca se divide en subtareas para la ejecución paralela.

Finalmente, una aplicación también puede ser concurrente y paralela, ya que funciona en varias tareas al mismo tiempo y también divide cada tarea en subtareas para ejecución paralela. Sin embargo, algunos de los beneficios de la concurrencia y el paralelismo pueden perderse en este escenario, ya que las CPU de la computadora ya están bastante ocupadas con la concurrencia o el paralelismo. Combinarlo puede llevar a una pequeña ganancia de rendimiento o incluso a una pérdida de rendimiento.


La forma más simple y elegante de entender los dos en mi opinión es esta. La concurrencia permite el intercalado de la ejecución y, por lo tanto, puede dar la ilusión de paralelismo. Esto significa que un sistema concurrente puede ejecutar su video de Youtube junto con usted escribiendo un documento en Word, por ejemplo. El sistema operativo subyacente, al ser un sistema concurrente, permite a esas tareas intercalar su ejecución. Debido a que las computadoras ejecutan las instrucciones tan rápidamente, esto da la apariencia de hacer dos cosas a la vez.

El paralelismo es cuando tales cosas realmente están en paralelo. En el ejemplo anterior, es posible que el código de procesamiento de video se ejecute en un solo núcleo, y la aplicación de Word se ejecute en otro. Tenga en cuenta que esto significa que un programa concurrente también puede estar en paralelo! La estructuración de su aplicación con subprocesos y procesos permite a su programa explotar el hardware subyacente y, potencialmente, realizarse en paralelo.

¿Por qué no tener todo paralelo entonces? Una razón es porque la concurrencia es una forma de estructurar programas y es una decisión de diseño para facilitar la separación de preocupaciones, mientras que el paralelismo se usa a menudo en nombre del desempeño. Otra es que algunas cosas, fundamentalmente, no pueden hacerse completamente en paralelo. Un ejemplo de esto sería agregar dos cosas al final de una cola: no puede insertar ambas al mismo tiempo. Algo debe ir primero y el otro detrás, o si no, arruinarás la cola. Aunque podemos intercalar dicha ejecución (y así obtenemos una cola concurrente), no puede tenerla paralela.

¡Espero que esto ayude!


La noción de "concurrencia" de Pike es una decisión intencional de diseño e implementación. Un diseño de programa con capacidad concurrente puede o no exhibir un "paralelismo" de comportamiento; Depende del entorno de ejecución.

No desea que el paralelismo sea exhibido por un programa que no fue diseñado para la concurrencia. :-) Pero en la medida en que sea una ganancia neta para los factores relevantes (consumo de energía, rendimiento, etc.), desea un diseño de máxima concurrencia para que el sistema host pueda paralelizar su ejecución cuando sea posible.

El lenguaje de programación de Pike''s Go ilustra esto de manera extrema: sus funciones son todos los hilos que pueden ejecutarse correctamente al mismo tiempo, es decir, llamar a una función siempre crea un hilo que se ejecutará en paralelo con la persona que llama si el sistema es capaz de hacerlo. Una aplicación con cientos o incluso miles de hilos es perfectamente normal en su mundo. (No soy un experto en Go, eso es solo mi opinión).