¿Qué tan importante es el multihilo en la industria actual del software? [cerrado]

59

Tengo cerca de 3 años de experiencia escribiendo aplicaciones web en Java usando marcos MVC (como struts). Nunca he escrito código multiproceso hasta ahora, aunque he escrito código para las principales cadenas minoristas.

Recibo algunas preguntas sobre subprocesos múltiples durante las entrevistas y las respondo generalmente (en su mayoría preguntas simples). Esto me dejó preguntándome qué tan importante es Multithreading en el escenario actual de la industria.

usuario2434
fuente
8
Es posible que no lo haya hecho explícitamente, pero definitivamente lo ha aprovechado detrás de escena.
Martin York
1
Rara vez trabajo con código multiproceso para el trabajo, pero trato de leerlo / poder discutirlo durante una entrevista. No me gustaría trabajar con codificadores que no reciben hilos, y no me gustaría trabajar con codificadores que no les importa si otros codificadores obtienen hilos.
Trabajo
1
Raramente lo uso en desarrollo web, pero creo que es más común en otros lugares. Por ejemplo, yo estaba escribiendo recientemente una aplicación para Android y se dio cuenta que estás obligado a usar multihilo si tiene alguna actividad de la red.
jwegner
44
No es importante el subprocesamiento múltiple, es la computación paralela. Si cree que todo lo que va a su aplicación web está en el hilo ... debe estar fumando algo.
user606723
1
La capacidad de "Pensar fuera del hilo" es muy buena incluso para la programación de un solo hilo. Da mucho menos por sentado, y su código es generalmente más robusto y reutilizable.
corsiKa

Respuestas:

92

Es extremadamente importante

Sin embargo, lo más importante es comprender que el subprocesamiento múltiple es solo una forma de resolver el problema de asincronía. El entorno técnico en el que muchas personas ahora escriben software difiere del entorno histórico de desarrollo de software (de aplicaciones monolíticas que realizan cálculos por lotes) en dos formas clave:

  • Las máquinas de muchos núcleos ahora son comunes. Ya no podemos esperar que la velocidad del reloj o la densidad del transistor aumenten en órdenes de magnitud. El precio de la computación seguirá bajando, pero caerá debido a un gran paralelismo. Tendremos que encontrar una manera de aprovechar ese poder.

  • Las computadoras ahora están muy conectadas en red y las aplicaciones modernas dependen de la capacidad de obtener información rica de una variedad de fuentes.

Desde un punto de vista computacional, estos dos factores se reducen esencialmente a la misma idea central: la información estará cada vez más disponible de forma asíncrona . Si la información que necesita se calcula en otro chip en su máquina o en un chip al otro lado del mundo, realmente no importa. De cualquier manera, su procesador está sentado allí quemando miles de millones de ciclos por segundo esperando información cuando podría estar haciendo un trabajo útil.

Entonces, lo que importa ahora, y lo que importará aún más en el futuro, no es el subprocesamiento múltiple per se, sino que se trata de la asincronía . El subprocesamiento múltiple es solo una forma de hacerlo: una forma complicada y propensa a errores que solo se volverá más complicada y propensa a errores a medida que los chips de modelo de memoria débil se usen más ampliamente.

El desafío para los proveedores de herramientas es encontrar algo mejor que el subprocesamiento múltiple para que nuestros clientes manejen la infraestructura asincrónica que usarán en el futuro.

Eric Lippert
fuente
55
+1 por una excelente respuesta, merece más crédito que mi humilde intento.
Péter Török
2
La información estará cada vez más disponible de forma asincrónica. Si eso no es la verdad. . .
Surfasb
2
concurrencyEs más importante que el asynchronous comportamiento. Puede tener asíncrono sin concurrencia (es decir, varios subprocesos en una CPU de un solo núcleo) asynchronousno es un sustituto semántico concurrency.
55
@Jarrod: domar la asincronía es más importante que simplemente dominar la concurrencia precisamente por la razón que mencionas: la concurrencia es solo un tipo de asincronía particularmente difícil. La parte difícil de la concurrencia no es el aspecto de "cosas que suceden al mismo tiempo" y, de hecho, la concurrencia es a menudo solo simultaneidad simulada , por ejemplo, la multitarea no cooperativa a través de la división del tiempo. La parte difícil es usar eficientemente los recursos sin bloquear, colgar, bloquear y sin escribir de adentro hacia afuera programas que son difíciles de razonar localmente.
Eric Lippert
"la concurrencia es a menudo solo simultaneidad simulada, por ejemplo, multitarea no cooperativa a través de la división del tiempo": en mi opinión, esto sigue siendo (verdadera) concurrencia, ¿tal vez quiere decir que no es paralelismo?
Giorgio el
46

Se está volviendo cada vez más importante a medida que los procesadores modernos tienen cada vez más núcleos. Hace una década, la mayoría de las computadoras existentes tenían un solo procesador, por lo que el subprocesamiento múltiple era importante solo en aplicaciones de servidor de gama alta. Hoy en día, incluso las computadoras portátiles básicas tienen procesadores multinúcleo. En pocos años, incluso dispositivos móviles ... Por lo tanto, se requiere más y más código para usar las ventajas potenciales de rendimiento de la concurrencia y para ejecutarse correctamente en un entorno multiproceso.

Péter Török
fuente
3
+1: más importante que nunca. Recuerde también que en un diseño de sistema, también puede obtener los beneficios del subprocesamiento múltiple simplemente dividiendo el trabajo para que más procesos lo hagan.
Scott C Wilson
11
¡Muchos dispositivos móviles ya tienen procesadores multi-core!
Che Jami
3
Yo diría que el subprocesamiento múltiple ha sido importante desde que se creó el primer sistema de tiempo compartido. Tener múltiples procesadores / núcleos solo agrega una nueva dimensión de eficiencia a tener múltiples hilos.
jwernerny
Tal vez (especialmente en dispositivos móviles) hilos es una mala idea. El sistema operativo probablemente debería manejar la optimización del uso de los núcleos sin que el código de usuario con errores intente realizar subprocesos. Hay muy pocas aplicaciones que un usuario normal tenga acceso a esa necesidad o se beneficiaría para multitudes. La única excepción son (aplicaciones gráficas de alta gama / herramientas de desarrollo / modelado meteorológico / servidores web (y servicios asociados)) todas las aplicaciones especializadas de alta gama.
Martin York
1
@ Tux-D, es muy posible que tengas un juego en un dispositivo móvil que utilice más de un núcleo. No es algo excepcional.
whitequark
28

En general, el subprocesamiento múltiple ya es bastante importante, y solo se volverá más importante en los próximos años (como señaló Péter Török): así es como los procesadores se escalarán para el futuro previsible (más núcleos en lugar de MHz más alto) .

En su caso, sin embargo, parece estar trabajando principalmente con aplicaciones web. Las aplicaciones web, por su naturaleza, son multiproceso debido a la forma en que su servidor web procesa las solicitudes de cada usuario (es decir, en paralelo). Si bien es probable que sea importante que comprenda la concurrencia y la seguridad de los subprocesos (especialmente cuando se trata de cachés y otros datos compartidos), dudo que se encuentre con demasiados casos en los que sea beneficioso realizar múltiples subprocesos internos del código de la aplicación web (es decir, varios trabajadores hilos por solicitud). En ese sentido, creo que ser un experto en multihilo no es realmente necesario para un desarrollador web. A menudo se pregunta en las entrevistas, porque es un tema bastante complicado, y también porque muchos entrevistadores solo hacen algunas preguntas en Google 10 minutos antes de llegar allí.

Daniel B
fuente
+1 para la nota de que el póster es un desarrollador web y que la mayoría de los contenedores de servidores web realizan una cantidad decente de trabajo de subprocesamiento múltiple para usted. No es que elimine la necesidad en algunos casos, pero el 99% del tiempo el código del controlador de subprocesos múltiples no es la mayor mejora de rendimiento para una llamada MVC.
Mufasa
19

Multi-threading es un arenque rojo. Multi-threading es un detalle de implementación para el problema real que es la concurrencia . No todos los programas de subprocesos son concurrentes debido a bloqueos y lo que no.

Los subprocesos son solo un modelo y un patrón de implementación para implementar concurrentprogramas.

Por ejemplo, puede escribir software altamente escalable y tolerante a fallas sin necesidad de realizar múltiples subprocesos en idiomas como Erlang.


fuente
+1 aunque sigo pensando que Erlang es multiproceso; la comunidad acaba de redefinir la palabra "hilo" para depender de un estado compartido mutable, y así distinguirse de él.
Dan
1
Erlang VM utiliza 1 subproceso por CPU de forma predeterminada, pero como desarrollador de Erlang, no tiene acceso a los subprocesos subyacentes del sistema operativo solo a los procesos livianos que suministra Erlang VM.
10

Recibo algunas preguntas sobre multihilo durante las entrevistas ...

Bueno, para pasar las entrevistas, el multihilo puede ser bastante importante. Citando a sí mismo , "al entrevistar a candidatos para nuestro equipo, hago preguntas de concurrencia no porque estas habilidades sean importantes en nuestro proyecto ( no lo son ) sino porque de alguna manera me hacen más fácil evaluar el conocimiento general del lenguaje que usamos ..."

mosquito
fuente
2
Tener alguna idea sobre la programación simultánea y de subprocesos múltiples también se traduce generalmente en un enfoque defensivo, que puede ser algo muy bueno. Si tiene que tener en cuenta que algo completamente no relacionado dentro de su proceso puede o no adelantarse a una sola declaración lógica y ejecutarse en el medio de todo lo demás, entonces debe planificar esa posibilidad. Las implementaciones de subprocesos múltiples (a diferencia de otras formas de concurrencia) simplemente significa que tiene la carga adicional de que puede hacer algo a cualquier estado que no sea hilo local.
un CVn
6

Comprender cómo aprovechar el subproceso para mejorar el rendimiento es una habilidad crítica en el entorno de software actual, para la mayoría de las industrias y aplicaciones.

Como mínimo, la comprensión de los problemas relacionados con la concurrencia debe ser un hecho.

La nota obvia de que no todas las aplicaciones o entornos podrán aprovecharlo se aplica, por ejemplo, en muchos sistemas integrados. Sin embargo, parece que el procesador Atom (et al) parece estar trabajando para cambiar eso (el multinúcleo liviano comienza a ser más común).

Stephen
fuente
4

Parece que ya estás escribiendo código multiproceso.

La mayoría de las aplicaciones web Java pueden manejar múltiples solicitudes al mismo tiempo, y lo hacen mediante el uso de múltiples hilos.

Por lo tanto, diría que es importante conocer los conceptos básicos al menos.

Tom Jefferys
fuente
18
<nitpick> aparentemente (s) no está escribiendo código multiproceso, solo código (único subproceso) que se ejecuta en un entorno multiproceso. </nitpick>
Péter Török
2

Sigue siendo importante en situaciones donde lo necesita, pero como muchas cosas en desarrollo, es la herramienta adecuada para el trabajo correcto. Estuve 3 años sin tocar hilos, ahora prácticamente todo lo que hago tiene algunos motivos. Con los procesadores multinúcleo todavía existe una gran necesidad de subprocesos, pero todas las razones tradicionales siguen siendo válidas, todavía desea interfaces receptivas y aún puede ser capaz de lidiar con la sincronización y continuar con otras cosas a la vez.

Nicholas Smith
fuente
2

Respuesta corta: muy.

Respuesta más larga: las computadoras electrónicas (basadas en transistores) se están acercando rápidamente a los límites físicos de la tecnología. Cada vez es más difícil exprimir más relojes de cada núcleo mientras se gestiona la generación de calor y los efectos cuánticos de los circuitos microscópicos (las rutas de los circuitos ya se están colocando tan juntas en los chips modernos que un efecto llamado "túnel cuántico" puede hacer un electrón "saltar las pistas" de un circuito a otro, sin necesidad de las condiciones adecuadas para un arco eléctrico tradicional); por lo tanto, prácticamente todos los fabricantes de chips se están centrando en hacer que cada reloj pueda hacer más, al poner más "unidades de ejecución" en cada CPU. Luego, en lugar de que la computadora haga una sola cosa por reloj, puede hacer 2, 4 o incluso 8. Intel tiene "HyperThreading", que básicamente divide un núcleo de CPU en dos procesadores lógicos (con algunas limitaciones). Prácticamente todos los fabricantes están colocando al menos dos núcleos de CPU separados en un chip de CPU, y el estándar de oro actual para las CPU de escritorio es de cuatro núcleos por chip. Ocho es posible cuando se usan dos chips de CPU, hay placas base de servidor diseñadas para procesadores "quad quad-core" (16 UE más HT opcional), y es probable que la próxima generación de CPU tenga seis u ocho por chip.

El resultado de todo esto es que, para aprovechar al máximo la forma en que las computadoras están ganando potencia informática, debe ser capaz de permitir que la computadora "divida y conquiste" su programa. Los lenguajes administrados tienen al menos un hilo GC que maneja la administración de memoria por separado de su programa. Algunos también tienen hilos de "transición" que manejan interoperabilidad COM / OLE (tanto para proteger el "sandbox" administrado como para el rendimiento). Sin embargo, más allá de eso, realmente debe comenzar a pensar en cómo su programa puede hacer varias cosas simultáneamente y diseñar su programa con características diseñadas para permitir que las partes del programa se manejen de forma asincrónica. Windows y los usuarios de Windows prácticamente esperarán que su programa realice tareas largas y complicadas en subprocesos en segundo plano, que mantienen la interfaz de usuario de su programa (que se ejecuta en el hilo principal del programa) "sensible" al bucle de mensajes de Windows. Obviamente, los problemas que tienen soluciones paralelizables (como la clasificación) son candidatos naturales, pero hay un número finito de tipos de problemas que se benefician de la paralelización.

KeithS
fuente
1

Solo una advertencia sobre subprocesos múltiples: más subprocesos no significan una mejor eficiencia. Si no se gestiona correctamente, pueden ralentizar el sistema. El actor de Scala mejora el subproceso de Java y maximiza el uso del sistema (lo mencionó como un desarrollador de Java).

EDITAR: Aquí hay algunas cosas a tener en cuenta sobre las desventajas de los subprocesos múltiples:

  • interferencia de hilos entre sí al compartir recursos de hardware
  • Los tiempos de ejecución de un solo subproceso no se mejoran, pero pueden degradarse, incluso cuando solo se está ejecutando un subproceso. Esto se debe a frecuencias más lentas y / o etapas de tubería adicionales que son necesarias para acomodar el hardware de conmutación de hilos.
  • El soporte de hardware para subprocesos múltiples es más visible para el software, por lo que requiere más cambios tanto en los programas de aplicación como en los sistemas operativos que el Multiprocesamiento.
  • Dificultad para gestionar la concurrencia.
  • Dificultad de prueba.

Además, este enlace podría ser de alguna ayuda sobre lo mismo.

c0da
fuente
2
Esto no parece responder a la pregunta del OP: - /
Péter Török
Sin embargo, ofrece una vista de nivel superior (más) de subprocesos. Una cosa a tener en cuenta antes de profundizar en multi-threading.
c0da
@ c0da Stack Exchange no es un panel de discusión: las respuestas deben responder directamente a la pregunta. ¿Puede ampliar su respuesta para devolverla a lo que está buscando el autor de la pregunta?
1

Esto me dejó preguntándome qué tan importante es Multithreading en el escenario actual de la industria.

En los campos críticos de rendimiento donde el rendimiento no proviene del código de terceros que hace el trabajo pesado, sino el nuestro, entonces tendería a considerar las cosas en este orden de importancia desde la perspectiva de la CPU (GPU es un comodín que gané entrar):

  1. Eficiencia de memoria (ej .: localidad de referencia).
  2. Algorítmico
  3. Multithreading
  4. SIMD
  5. Otras optimizaciones (sugerencias de predicción de rama estática, por ejemplo)

Tenga en cuenta que esta lista no se basa únicamente en la importancia, sino en muchas otras dinámicas, como el impacto que tienen en el mantenimiento, qué tan sencillas son (si no, vale la pena considerarlas más de antemano), sus interacciones con otros en la lista, etc.

Eficiencia de memoria

La mayoría podría sorprenderse de mi elección de eficiencia de memoria en lugar de algorítmica. Esto se debe a que la eficiencia de la memoria interactúa con los otros 4 elementos de esta lista, y es porque su consideración a menudo está muy en la categoría de "diseño" en lugar de la categoría de "implementación". Es cierto que aquí hay un pequeño problema de gallina o huevo, ya que comprender la eficiencia de la memoria a menudo requiere considerar los 4 elementos de la lista, mientras que los otros 4 elementos también requieren considerar la eficiencia de la memoria. Sin embargo, está en el corazón de todo.

Por ejemplo, si necesitamos una estructura de datos que ofrezca acceso secuencial en tiempo lineal e inserciones en tiempo constante en la parte posterior y nada más para elementos pequeños, la opción ingenua para alcanzar sería una lista vinculada. Eso sin tener en cuenta la eficiencia de la memoria. Cuando consideramos la eficiencia de la memoria en la mezcla, terminamos eligiendo estructuras más contiguas en este escenario, como estructuras basadas en arreglos de crecimiento o más nodos contiguos (por ejemplo: uno que almacena 128 elementos en un nodo) unidos entre sí, o al menos una lista vinculada respaldada por un asignador de agrupación. Estos tienen una ventaja dramática a pesar de tener la misma complejidad algorítmica. Del mismo modo, a menudo elegimos el ordenamiento rápido de una matriz sobre el tipo de combinación a pesar de una complejidad algorítmica inferior simplemente debido a la eficiencia de la memoria.

Del mismo modo, no podemos tener múltiples subprocesos eficientes si nuestros patrones de acceso a la memoria son tan granulares y de naturaleza dispersa que terminamos maximizando la cantidad de intercambio falso mientras bloqueamos los niveles más granulares en el código. Entonces, la eficiencia de la memoria multiplica la eficiencia de subprocesos múltiples. Es un requisito previo para aprovechar al máximo los hilos.

Cada uno de los elementos anteriores en la lista tiene una interacción compleja con los datos, y centrarse en cómo se representan los datos está en última instancia en la línea de la eficiencia de la memoria. Cada uno de estos anteriores puede tener un cuello de botella con una forma inapropiada de representar o acceder a los datos.

Otra razón por la eficiencia de la memoria es tan importante es que se puede aplicar a lo largo de una entera código base. En general, cuando la gente imagina que las ineficiencias se acumulan de pequeñas secciones de trabajo aquí y allá, es una señal de que necesitan tomar un perfilador. Sin embargo, los campos de baja latencia o los que se ocupan de hardware muy limitado encontrarán, incluso después de la creación de perfiles, sesiones que indican que no hay puntos de acceso claros (solo veces dispersos por todas partes) en una base de código que es claramente ineficiente con la forma en que se asigna, copia y accediendo a la memoria. Por lo general, esta es la única vez que una base de código completa puede ser susceptible a un problema de rendimiento que podría conducir a un conjunto completamente nuevo de estándares aplicados en toda la base de código, y la eficiencia de la memoria es a menudo el núcleo de la misma.

Algorítmico

Este es más o menos un hecho, ya que la elección en un algoritmo de clasificación puede marcar la diferencia entre una entrada masiva que toma meses para ordenar versus segundos para ordenar. Tiene el mayor impacto de todos si la elección es entre, digamos, algoritmos cuadráticos o cúbicos realmente por debajo del par y uno linealithmic, o entre lineal y logarítmico o constante, al menos hasta que tengamos 1,000,000 de máquinas centrales (en cuyo caso memoria la eficiencia se volvería aún más importante).

Sin embargo, no está en la parte superior de mi lista personal, ya que cualquier persona competente en su campo sabría usar una estructura de aceleración para el sacrificio de arranque, por ejemplo, estamos saturados de conocimiento algorítmico y de saber cosas como usar una variante de un método como un árbol de radix para búsquedas basadas en prefijos son cosas de bebé. Al carecer de este tipo de conocimiento básico del campo en el que estamos trabajando, la eficiencia algorítmica ciertamente se elevaría a la cima, pero a menudo la eficiencia algorítmica es trivial.

También inventar nuevos algoritmos puede ser una necesidad en algunos campos (por ejemplo, en el procesamiento de mallas he tenido que inventar cientos ya que antes no existían, o las implementaciones de características similares en otros productos eran secretos de propiedad, no publicados en un documento ) Sin embargo, una vez que hemos pasado la parte de resolución de problemas y encontramos una manera de obtener los resultados correctos, y una vez que la eficiencia se convierte en el objetivo, la única forma de obtenerla realmente es considerar cómo estamos interactuando con los datos (memoria). Sin comprender la eficiencia de la memoria, el nuevo algoritmo puede volverse innecesariamente complejo con esfuerzos inútiles para hacerlo más rápido, cuando lo único que necesitaba era un poco más de consideración de la eficiencia de la memoria para producir un algoritmo más simple y elegante.

Por último, los algoritmos tienden a estar más en la categoría de "implementación" que en la eficiencia de la memoria. A menudo son más fáciles de mejorar en retrospectiva, incluso con un algoritmo subóptimo utilizado inicialmente. Por ejemplo, un algoritmo de procesamiento de imágenes inferior a menudo solo se implementa en un lugar local en la base de código. Se puede cambiar por uno mejor más adelante. Sin embargo, si todos los algoritmos de procesamiento de imágenes están vinculados a una Pixelinterfaz que tiene una representación de memoria subóptima, pero la única forma de corregirla es cambiar la forma en que se representan múltiples píxeles (y no uno solo), entonces a menudo estamos SOL y tendrá que reescribir completamente la base de código hacia unImageinterfaz. El mismo tipo de cosas se aplica para reemplazar un algoritmo de clasificación: generalmente es un detalle de implementación, mientras que un cambio completo en la representación subyacente de los datos que se ordenan o la forma en que se pasan a través de los mensajes puede requerir el rediseño de las interfaces.

Multithreading

El subprocesamiento múltiple es difícil en el contexto del rendimiento, ya que es una optimización de nivel micro que juega con las características del hardware, pero nuestro hardware realmente está escalando en esa dirección. Ya tengo compañeros que tienen 32 núcleos (solo tengo 4).

Sin embargo, mulithreading es una de las micro optimizaciones más peligrosas que probablemente conoce un profesional si el propósito se usa para acelerar el software. La condición de carrera es prácticamente el error más mortal posible, ya que es de naturaleza tan indeterminada (tal vez solo aparece una vez cada pocos meses en la máquina de un desarrollador en el momento más inconveniente fuera del contexto de depuración, si es que lo hace). Por lo tanto, podría decirse que es la degradación más negativa en la mantenibilidad y la posible corrección del código entre todos estos, especialmente porque los errores relacionados con el subprocesamiento múltiple pueden pasar fácilmente por alto incluso las pruebas más cuidadosas.

Sin embargo, se está volviendo tan importante. Si bien puede que no siempre supere algo como la eficiencia de la memoria (que a veces puede hacer las cosas cien veces más rápido) dada la cantidad de núcleos que tenemos ahora, estamos viendo más y más núcleos. Por supuesto, incluso con máquinas de 100 núcleos, todavía pondría la eficiencia de la memoria en la parte superior de la lista, ya que la eficiencia de los hilos generalmente es imposible sin ella. Un programa puede usar cientos de subprocesos en una máquina de este tipo y aún ser lento sin una representación eficiente de memoria y patrones de acceso (que se vincularán con patrones de bloqueo).

SIMD

SIMD también es un poco incómodo ya que los registros en realidad se están ampliando, con planes para hacerlo aún más. Originalmente vimos registros MMX de 64 bits seguidos de registros XMM de 128 bits capaces de realizar 4 operaciones SPFP en paralelo. Ahora estamos viendo registros YMM de 256 bits capaces de 8 en paralelo. Y ya hay planes para registros de 512 bits que permitirían 16 en paralelo.

Estos interactuarían y se multiplicarían con la eficiencia del subprocesamiento múltiple. Sin embargo, SIMD puede degradar la capacidad de mantenimiento tanto como el subprocesamiento múltiple. Aunque los errores relacionados con ellos no son necesariamente tan difíciles de reproducir y corregir como un punto muerto o una condición de carrera, la portabilidad es incómoda y garantizar que el código pueda ejecutarse en la máquina de todos (y usar las instrucciones apropiadas basadas en sus capacidades de hardware) torpe.

Otra cosa es que, si bien los compiladores de hoy en día generalmente no superan el código SIMD escrito por expertos, sí superan fácilmente los intentos ingenuos. Podrían mejorar hasta el punto en que ya no tengamos que hacerlo manualmente, o al menos sin tener que hacerlo de manera tan manual como para escribir intrínsecos o código de ensamblaje directo (tal vez solo una pequeña guía humana).

Sin embargo, de nuevo, sin un diseño de memoria que sea eficiente para el procesamiento vectorizado, SIMD es inútil. Terminaremos cargando un campo escalar en un registro amplio solo para realizar una operación en él. En el corazón de todos estos elementos hay una dependencia de los diseños de memoria para ser verdaderamente eficientes.

Otras optimizaciones

A menudo, esto es lo que sugeriría que empecemos a llamar "micro" hoy en día si la palabra sugiere no solo ir más allá del enfoque algorítmico sino hacia cambios que tienen un impacto minúsculo en el rendimiento.

A menudo, tratar de optimizar la predicción de rama requiere un cambio en el algoritmo o la eficiencia de la memoria, por ejemplo, si esto se intenta simplemente a través de sugerencias y reordenando el código para la predicción estática, eso solo tiende a mejorar la ejecución por primera vez de dicho código, lo que hace que los efectos sean cuestionables si no suele ser despreciable.

Volver a Multithreading para rendimiento

De todos modos, ¿cuán importante es el subprocesamiento múltiple desde un contexto de rendimiento? En mi máquina de 4 núcleos, idealmente puede hacer las cosas 5 veces más rápido (lo que puedo obtener con hyperthreading). Sería considerablemente más importante para mi colega que tiene 32 núcleos. Y será cada vez más importante en los próximos años.

Entonces es bastante importante. Pero es inútil simplemente lanzar un montón de hilos al problema si la eficiencia de la memoria no está ahí para permitir que los bloqueos se usen con moderación, para reducir el intercambio falso, etc.

Multithreading fuera del rendimiento

El subprocesamiento múltiple no siempre se trata de un rendimiento absoluto en un sentido directo de rendimiento. A veces se usa para equilibrar una carga incluso con el posible costo de rendimiento para mejorar la capacidad de respuesta al usuario, o para permitir que el usuario realice más tareas múltiples sin esperar a que termine (por ejemplo: continuar navegando mientras descarga un archivo).

En esos casos, sugeriría que el subprocesamiento múltiple se eleve aún más hacia la parte superior (posiblemente incluso por encima de la eficiencia de la memoria), ya que se trata del diseño del usuario final en lugar de aprovechar al máximo el hardware. A menudo dominará los diseños de interfaz y la forma en que estructuramos toda nuestra base de código en tales escenarios.

Cuando no estamos simplemente paralelizando un circuito cerrado que accede a una estructura de datos masiva, el subprocesamiento múltiple va a la categoría de "diseño" realmente hardcore, y el diseño siempre triunfa sobre la implementación.

Entonces, en esos casos, diría que considerar el subprocesamiento múltiple es absolutamente crítico, incluso más que la representación y el acceso a la memoria.


fuente
0

La programación concurrente y paralela es lo que se está volviendo importante. Los subprocesos son solo un modelo de programación para hacer varias cosas al mismo tiempo (y no en pseudo-paralelo como solía ser antes del surgimiento de los procesadores multi-core). Multi-threading es (en mi humilde opinión) criticado por ser complejo y peligroso ya que los hilos comparten muchos recursos y el programador es responsable de hacerlos cooperar. De lo contrario, terminará con puntos muertos que son difíciles de depurar.

sakisk
fuente
0

Dado que es posible que necesitemos contactar muchas aplicaciones externas, puede haber algún proceso en segundo plano en el que la interacción del sistema externo tome más tiempo y el usuario final no pueda esperar hasta que el proceso haya terminado. así que Multithreading es importante ...

que estamos utilizando en nuestra aplicación, primero intentamos contactarnos con el sistema externo si está inactivo, luego guardamos la solicitud en la Base de datos y abarcamos un hilo para finalizar el proceso en segundo plano. Puede ser necesario en las operaciones por lotes también.

TPReddy
fuente
0

Históricamente, la gente tuvo que luchar haciendo programación multiproceso a mano. Tenían que trabajar con todos los componentes centrales (hilos, semáforos, mutexes, bloqueos, etc.) directamente.

Todos estos esfuerzos dieron como resultado aplicaciones que pudieron escalar agregando cpus adicionales a un solo sistema. Esta escalabilidad vertical está limitada por "cuál es el servidor más grande que puedo comprar".

Hoy en día veo un cambio hacia el uso de más marcos y diferentes modelos de diseño para el diseño de software. MapReduce es uno de esos modelos que se centra en el procesamiento por lotes.

El objetivo es escalar horizontalmente. Agregar más servidores estándar en lugar de comprar servidores más grandes.

Dicho esto, el hecho es que comprender realmente la programación multiproceso es muy importante. He estado en una situación en la que alguien creó una condición de carrera y ni siquiera sabía qué era una condición de carrera hasta que notamos errores extraños durante las pruebas.

Niels Basjes
fuente
-1

Mi máquina tiene 8 núcleos. En el Administrador de tareas, tengo 60 procesos en ejecución. Algunos, como VS, usan hasta 98 ​​hilos. Outlook usa 26. Espero que la mayor parte de mi uso de memoria sean las pilas asignadas a cada uno de esos subprocesos inactivos.

Estoy personalmente esperando que salga la computadora de 300 núcleos para no tener que esperar a que Outlook responda. Por supuesto, para entonces Outlook usará 301 hilos.

El subprocesamiento múltiple solo es importante si está creando sistemas que serán el único proceso importante en la computadora en un momento determinado (p. Ej., Motores de cálculo). Las aplicaciones de escritorio probablemente le harían un favor al usuario al no usar todos los núcleos disponibles. Las aplicaciones web que utilizan el modelo de solicitud / respuesta son inherentemente multiproceso.

Es importante para los diseñadores de marcos y lenguaje, y los programadores de sistemas de back-end, no tanto para los creadores de aplicaciones. Sin embargo, probablemente valga la pena comprender algunos conceptos básicos, como bloquear y escribir código asíncrono.

Paul Stovell
fuente
A menudo golpeo algo en un hilo de fondo, como una carga de DB larga, pero es muy raro que tenga que lidiar con condiciones de carrera o bloqueos, etc. (de hecho, probablemente nunca)
Aran Mulholland