Buena pregunta, o al menos una con una respuesta interesante. Parte de esta respuesta muestra un mundo en el que las CPU podrían escalar eficientemente en ancho en lugar de con múltiples núcleos separados. ¡Los modelos de licencia / precio serían diferentes!
El resto explica por qué no pueden. Resumen:
- El costo de múltiples núcleos escala de forma lineal
- El costo de ampliar las escalas de la tubería superescalar de 1 núcleo ~ cuadráticamente Esto es factible con suficiente fuerza bruta, hasta cierto punto de todos modos. El rendimiento de un solo subproceso es muy importante para el uso interactivo (la latencia de extremo a extremo es importante, no solo el rendimiento), por lo que las CPU de gama alta de núcleo grande actuales pagan ese precio. por ejemplo, Skylake (4 de ancho), Ryzen (5 o 6 de ancho) y Apple A12 (7 de ancho para los núcleos grandes, 3 de ancho para los núcleos pequeños con eficiencia energética)
- El IPC decreciente grave regresa de solo ampliar la tubería más allá de 3 o 4 de ancho, incluso con la ejecución fuera de orden para encontrar el ILP . Las fallas de ramificación y de caché son difíciles, y todavía bloquean toda la tubería.
No mencionó la frecuencia, solo IPC, pero la frecuencia de escala también es difícil. Una frecuencia más alta requiere un voltaje más alto, por lo que la potencia se escala con frecuencia en cubos : ^1
desde la frecuencia directamente y ^2
desde el voltaje. (La energía almacenada por el capacitor se escala con V ^ 2, y la mayor parte de la potencia dinámica más allá de la corriente de fuga proviene de la carga de bombeo hacia las cargas capacitivas de las puertas FET + cables).
Rendimiento = frecuencia multiplicado por IPC. (Dentro de la misma arquitectura. El SIMD más amplio le permite realizar el mismo trabajo con menos instrucciones, y algunos ISA son más densos que otros, por ejemplo, MIPS a menudo toma más instrucciones para hacer el mismo trabajo que x86 o AArch64).
Los costos están en el área de la matriz (costo de fabricación) y / o energía (lo que indirectamente limita la frecuencia porque el enfriamiento es difícil). Además, una menor potencia y rendimiento por vatio es un objetivo en sí mismo, especialmente para dispositivos móviles (batería) y servidores (densidad de energía / costos de enfriamiento / costos de electricidad).
Antes de que fuera multinúcleo por zócalo, tenía sistemas de múltiples zócalos para casos de uso de alta gama en los que deseaba un mayor rendimiento del que se podía lograr con una sola CPU que pudiera fabricarse, por lo que esos eran los únicos sistemas SMP. (Servidores, estaciones de trabajo de alta gama).
Si un solo núcleo pudiera escalar tan eficientemente como lo desea, tendríamos sistemas con 1 núcleo físico por socket, y SMT (por ejemplo, HyperThreading) para permitirles actuar como múltiples núcleos lógicos. Las computadoras de escritorio / portátiles típicas solo tendrían 1 núcleo físico, y no tendríamos problemas para paralelizar cosas que no se escalen linealmente con más núcleos. por ejemplo, make -j4
para aprovechar los servidores de múltiples sockets y / o para ocultar la latencia de E / S en un escritorio. (O tal vez aún intentaríamos paralelizar mucho si el ancho de la tubería se escalara fácilmente, pero IPC no lo hizo, por lo que tuvimos que usar más subprocesos SMT). Su núcleo del sistema operativo aún necesitaría ejecutarse en todos los núcleos lógicos, a menos que la CPU Presentar SMT al sistema operativo era muy diferente, por lo que los algoritmos de programación paralela y el bloqueo aún serían necesarios allí.
Donald Knuth dijo en una entrevista de 2008
También podría hablar un poco sobre mi infelicidad personal con la tendencia actual hacia la arquitectura multinúcleo. Para mí, parece más o menos que los diseñadores de hardware se han quedado sin ideas, y que están tratando de pasar la culpa de la futura desaparición de la Ley de Moore a los escritores de software al darnos máquinas que funcionan más rápido solo en unos pocos puntos de referencia clave!
Sí, si pudiéramos tener CPUs milagrosas de un solo núcleo con un rendimiento 8 veces mayor en programas reales , probablemente aún las estaríamos usando. Con sistemas de doble socket solo cuando valía la pena pagar mucho más por un mayor rendimiento (no un rendimiento de subproceso único).
Múltiples CPU reducen los costos de cambio de contexto cuando se ejecutan múltiples programas (al permitir que realmente se ejecuten en paralelo en lugar de cambiar rápidamente entre ellos); la multitarea preventiva que interrumpe la maquinaria masiva fuera de servicio que tal CPU requeriría probablemente dañaría aún más de lo que lo hace ahora.
Físicamente, sería un solo núcleo (para una jerarquía de caché simple sin interconexiones entre núcleos) pero admitiría SMT (por ejemplo, HyperThreading de Intel) para que el software pudiera usarlo como 8 núcleos lógicos que compiten dinámicamente por los recursos de rendimiento. O cuando solo 1 hilo se está ejecutando / no está parado, obtendría el beneficio completo.
Por lo tanto, usaría múltiples subprocesos cuando eso fuera realmente más fácil / natural (por ejemplo, procesos separados que se ejecutan a la vez) o para problemas fácilmente paralelizados con cadenas de dependencia que evitarían maximizar el IPC de esta bestia.
Pero desafortunadamente es una ilusión de parte de Knuth que las CPU multi-core dejarán de ser una cosa en este momento.
Escalado de rendimiento de un solo hilo
Creo que si hicieran un equivalente de 1 núcleo de una CPU de 8 núcleos, ese núcleo tendría un aumento del 800% en IPC, por lo que obtendría el rendimiento completo en todos los programas, no solo aquellos que están optimizados para múltiples núcleos.
Sí, eso es verdad. Si fuera posible construir una CPU de este tipo, sería muy sorprendente. Pero creo que es literalmente imposible en el mismo proceso de fabricación de semiconductores (es decir, la misma calidad / eficiencia de los transistores). Ciertamente, no es posible con el mismo presupuesto de energía y área de matriz que una CPU de 8 núcleos, a pesar de que ahorraría en lógica para unir los núcleos, y no necesitaría tanto espacio para las cachés privadas por núcleo.
Incluso si permite aumentos de frecuencia (dado que el criterio real es trabajar por segundo, no trabajar por reloj), hacer incluso una CPU 2 veces más rápida sería un gran desafío.
Si fuera posible en cualquier lugar cerca del mismo presupuesto de energía y área de troquel (por lo tanto, costo de fabricación) construir una CPU de este tipo, sí, los proveedores de CPU ya las estarían construyendo de esa manera.
¿Específicamente los núcleos más o núcleos más anchos? sección, para obtener los antecedentes necesarios para comprender esta respuesta; comienza simple con el funcionamiento de las CPU canalizadas en orden, luego superescalar (varias instrucciones por reloj). Luego explica cómo llegamos a la pared de potencia en la era P4, lo que lleva al final del escalado de frecuencia fácil, dejando principalmente solo IPC y haciendo más trabajo por instrucción (por ejemplo, SIMD) como el camino hacia adelante, incluso con transistores más pequeños.
Ampliar una tubería (instrucciones máximas por reloj) generalmente aumenta el costo como ancho al cuadrado . Ese costo se mide en el área y / o la potencia del troquel, para una verificación de dependencia paralela más amplia (detección de peligros) y un planificador fuera de servicio más amplio para encontrar instrucciones listas para ejecutar. Y más puertos de lectura / escritura en su archivo de registro y caché si desea ejecutar instrucciones distintas a nop
. Especialmente si tiene instrucciones de 3 entradas como FMA o add-with-carry (2 registros + banderas).
También hay rendimientos decrecientes de IPC para ampliar las CPU ; la mayoría de las cargas de trabajo tienen un ILP (Paralelismo de nivel de instrucción) limitado a pequeña escala / corto alcance para que las CPU exploten, por lo que hacer que el núcleo sea más ancho no aumenta el IPC (instrucciones por reloj) si el IPC ya está limitado a menos del ancho del núcleo por cadenas de dependencia, errores de rama, errores de caché u otros bloqueos. Seguro que obtendrás una aceleración en algunos bucles desenrollados con iteraciones independientes, pero eso no es lo que la mayoría del código pasa la mayor parte del tiempo haciendo. Las instrucciones de comparación / ramificación constituyen el 20% de la mezcla de instrucciones en el código "típico", IIRC. (Creo que he leído números del 15 al 25% para varios conjuntos de datos).
Además, una falta de caché que detiene todas las instrucciones dependientes (y luego todo una vez que se alcanza la capacidad ROB) cuesta más para una CPU más amplia. (El costo de oportunidad de dejar inactivas más unidades de ejecución; no se realiza más trabajo potencial). O una omisión de rama de manera similar provoca una burbuja.
Para obtener 8 veces el IPC, necesitaríamos al menos una mejora de 8 veces en la precisión de predicción de rama y en las tasas de aciertos de caché . Pero las tasas de aciertos de caché no se escalan bien con la capacidad de caché más allá de cierto punto para la mayoría de las cargas de trabajo. Y la captación previa de HW es inteligente, pero no puede ser tan inteligente. Y a 8 veces el IPC, los predictores de rama necesitan producir 8 veces más predicciones por ciclo, además de hacer que sean más precisos.
Las técnicas actuales para construir CPU de ejecución fuera de orden solo pueden encontrar ILP en rangos cortos . Por ejemplo, el tamaño ROB de Skylake es 224 uops de dominio fusionado, el planificador para uops no ejecutados es 97 dominio no fusionado. Consulte Comprender el impacto de lfence en un bucle con dos cadenas de dependencia largas para conocer las longitudes de un caso en el que el tamaño del planificador es el factor limitante para extraer ILP de 2 cadenas largas de instrucciones, si son demasiado largas. Y / o vea esta respuesta más general e introductoria ).
Por lo tanto, encontrar ILP entre dos bucles largos separados no es algo que podamos hacer con el hardware. La recompilación binaria dinámica para la fusión en bucle podría ser posible en algunos casos, pero difícil y no es algo que las CPU realmente puedan hacer a menos que sigan la ruta Transmeta Crusoe. (capa de emulación x86 en la parte superior de un ISA interno diferente; en ese caso, VLIW). Pero los diseños x86 modernos estándar con cachés uop y decodificadores potentes no son fáciles de superar para la mayoría de los códigos.
Y fuera de x86, todos los ISA que todavía están en uso son relativamente fáciles de decodificar, por lo que no hay motivación para la recopilación dinámica que no sean optimizaciones de larga distancia. TL: DR: esperar que los compiladores mágicos puedan exponer más ILP al hardware no funcionó para Itanium IA-64 , y es poco probable que funcione para una CPU súper ancha para cualquier ISA existente con un modelo de ejecución en serie.
Si tuvieras una CPU súper ancha, definitivamente querrías que sea compatible con SMT para que puedas mantenerlo alimentado con trabajo para hacer ejecutando múltiples subprocesos de bajo ILP.
Dado que Skylake actualmente tiene 4 uops de ancho (y logra un IPC real de 2 a 3 uops por reloj, o incluso más cerca de 4 en el código de alto rendimiento), ¡una CPU hipotética 8x más ancha tendría 32 de ancho!
Sería fantástico poder volver a dividir eso en 8 o 16 CPU lógicas que compartan dinámicamente esos recursos de ejecución: los subprocesos no bloqueados obtienen todo el ancho de banda de front-end y el rendimiento de back-end.
Pero con 8 núcleos separados, cuando un hilo se detiene, no hay nada más para mantener alimentadas las unidades de ejecución; los otros hilos no se benefician.
La ejecución a menudo es explosiva: se detiene esperando una carga perdida de caché, luego, una vez que llega, muchas instrucciones en paralelo pueden usar ese resultado. Con una CPU súper ancha, esa explosión puede ir más rápido y, de hecho, puede ayudar con SMT.
Pero no podemos tener CPU mágicas súper anchas
Por lo tanto, para obtener un rendimiento, debemos exponer el paralelismo al hardware en forma de paralelismo a nivel de hilo . En general, los compiladores no son buenos para saber cuándo / cómo usar hilos, excepto para casos simples como bucles muy grandes. (OpenMP o gcc's -ftree-parallelize-loops
). Todavía se necesita inteligencia humana para reelaborar el código para realizar eficientemente un trabajo útil en paralelo, porque la comunicación entre subprocesos es costosa, y también lo es el inicio del subproceso.
TLP es un paralelismo de grano grueso, a diferencia del ILP de grano fino dentro de un solo hilo de ejecución que HW puede explotar.
Las CPU dirigidas a cargas de trabajo interactivas (como Intel / AMD x86 y los núcleos de gama alta Apple / ARM AArch64) definitivamente influyen en los rendimientos decrecientes del escalado de IPC, porque el rendimiento de un solo subproceso sigue siendo tan valioso cuando la latencia importa, no solo el rendimiento para problemas masivamente paralelos.
Poder ejecutar 8 copias de un juego en paralelo a 15 fps cada una es mucho menos valioso que poder ejecutar una copia a 45 fps. Los proveedores de CPU saben esto, y es por eso que las CPU modernas utilizan la ejecución fuera de orden a pesar de que cuesta una gran cantidad de energía y área muerta. (Pero las GPU no lo hacen porque su carga de trabajo ya es masivamente paralela).
El hardware Xeon Phi de muchos núcleos de Intel (Knight's Landing / Knight's Mill) es un punto intermedio interesante: ejecución fuera de orden muy limitada y SMT para mantener núcleos de 2 anchos alimentados con instrucciones SIMD AVX512 para descifrar números. Los núcleos se basan en la arquitectura Silvermont de bajo consumo de Intel. (Ejecutivo fuera de servicio pero con una pequeña ventana de reordenamiento, mucho más pequeña que la familia Sandybridge de núcleo grande. Y una tubería más estrecha).
Por cierto, todo esto es ortogonal a SIMD. Hacer más trabajo por instrucción siempre ayuda, si es posible para su problema.
Modelos de precios
Los modelos de precios de software se basan en el panorama actual del hardware.
Los modelos de licencia por núcleo se generalizaron (y fueron relevantes incluso para equipos de escritorio de un solo socket) con la llegada de las CPU de múltiples núcleos. Antes de eso, solo era relevante para servidores y grandes estaciones de trabajo.
Si el software no necesitara múltiples núcleos para funcionar a la máxima velocidad, realmente no habría una forma de venderlo más barato a las personas que no obtienen tantos beneficios porque lo ejecutan en una CPU más débil. A menos que tal vez el ecosistema de software / hardware haya desarrollado controles en los "canales SMT" que le permiten configurar un ancho de ejecución máximo para el código que se ejecuta en ese núcleo lógico. (Nuevamente imaginando un mundo donde las CPU escalan en el ancho de la tubería en lugar de múltiples núcleos separados).