Se dice comúnmente que la arquitectura del procesador Itanium de 64 bits de Intel falló porque el revolucionario conjunto de instrucciones EPIC era muy difícil de escribir para un buen compilador, lo que significaba una falta de buenas herramientas de desarrollo para IA64, lo que significaba una falta de desarrolladores que crearan programas para la arquitectura , por lo que nadie quería usar hardware sin mucho software, y la plataforma falló, y todo por falta deun clavo de herradura buenos compiladores
Pero, ¿por qué el compilador era un problema técnico tan difícil? Me parece que si el paralelismo explícito en EPIC fue difícil de implementar para los proveedores de compiladores ... ¿por qué poner esa carga sobre ellos en primer lugar? No es que no existiera una solución buena y bien entendida para este problema: pon esa carga en Intel y da a los compiladores-escritores un objetivo más simple.
Itanium salió en 1997. En este punto, el sistema de código de bytes UCSD P-Code tenía casi 20 años, la máquina Z era un poco más joven y la JVM era la nueva estrella en ascenso en el mundo de los lenguajes de programación. ¿Hay alguna razón por la que Intel no especificó un lenguaje de "simple bytecode de Itanium" y proporcionó una herramienta que convierte este bytecode en un código EPIC optimizado, aprovechando su experiencia como las personas que diseñaron el sistema en primer lugar?
Respuestas:
Como recuerdo en ese momento, el problema no era solo los detalles de IA64, sino la competencia con el conjunto de instrucciones x86-64 de AMD. Al hacer que su arquitectura fuera compatible con el conjunto de instrucciones x86, AMD pudo aprovechar las herramientas existentes y los conjuntos de habilidades del desarrollador. El movimiento de AMD fue tan exitoso que Intel (y Via) se vieron esencialmente obligados a adoptar la arquitectura x86-64.
La gran barrera en ese momento era 4 GB de RAM en las PC de escritorio (más realista ~ 3.4GB utilizables en Windows). x86-64 rompió esa barrera y abrió una computación de mayor potencia para todos. Si AMD nunca hubiera presentado x86-64, estoy seguro de que Intel habría estado feliz de que todos los que quisieran saltar a 4GB + RAM pagaran una prima considerable durante años por ese privilegio. Demostrando cuán lentamente se mueven los mercados, las aplicaciones tardaron años en atrapar la programación multiproceso de hasta 64 bits, e incluso ahora 4 GB de RAM es estándar en las PC de gama baja.
En resumen, Intel intentó dar un salto revolucionario con la arquitectura IA64, y AMD dio un paso evolutivo con x86-64. En un mercado establecido, los pasos evolutivos que permiten a los trabajadores del conocimiento aprovechar las habilidades existentes ganarán pasos revolucionarios que requieren que todos aprendan nuevas habilidades. Independientemente de las diferencias cualitativas entre las arquitecturas, IA64 no pudo superar el impulso de su propia plataforma x86 una vez que AMD agregó las extensiones x86-64.
No compro la explicación de que IA64 era demasiado difícil de programar. Solo fue difícil en relación con las alternativas. El punto de @delnan sobre el IR de bajo nivel es acertado, simplemente no creo que hubiera hecho una diferencia.
En cuanto a por qué Intel no trató de soportar esa carga, ¿quién sabe? Eran el poder de mercado en ese momento. AMD era una amenaza, pero Intel era el rey de la colina. Tal vez pensaron que IA64 sería mucho mejor que cualquier otra cosa que podrían mover todo el mercado. Tal vez estaban tratando de hacer un nivel premium y dejar a AMD, VIA, etc. en el segundo nivel peleando por hardware básico de bajo margen, una estrategia que tanto Intel como Apple han empleado con bastante éxito.
¿Fue Itanium un intento deliberado de hacer una plataforma premium y sacar la alfombra de debajo de AMD, VIA, etc.? Por supuesto, así es como funcionan los negocios.
fuente
El artículo de Wikipedia sobre EPIC ya describió los muchos peligros comunes a VLIW y EPIC.
Si alguien no capta la sensación de fatalismo de ese artículo, permítanme resaltar esto:
En otras palabras, cualquier diseño de hardware que no pueda hacer frente a (*) la latencia no determinista del acceso a la memoria se convertirá en una falla espectacular.
(*) Al "hacer frente", es necesario lograr un rendimiento de ejecución razonablemente bueno (en otras palabras, "competitivo en costos"), lo que requiere no dejar que la CPU quede inactiva durante decenas a cientos de ciclos con tanta frecuencia.
Tenga en cuenta que la estrategia de afrontamiento empleada por EPIC (mencionada en el artículo de Wikipedia vinculado anteriormente) en realidad no resuelve el problema. Simplemente dice que la carga de indicar la dependencia de datos ahora recae en el compilador. Esta bien; el compilador ya tiene esa información, por lo que es sencillo para el compilador cumplirla. El problema es que la CPU seguirá inactiva durante decenas a cientos de ciclos a través de un acceso a memoria. En otras palabras, externaliza una responsabilidad secundaria, sin dejar de hacer frente a la responsabilidad primaria.
La pregunta puede reformularse como: "Dada una plataforma de hardware destinada a ser un fracaso, ¿por qué (1) no (2) no pudieron los escritores del compilador hacer un heroico esfuerzo para canjearla?"
Espero que mi reformulación haga obvia la respuesta a esa pregunta.
Hay un segundo aspecto del fracaso que también es fatal.
Las estrategias de afrontamiento (mencionadas en el mismo artículo) suponen que la captación previa basada en software se puede utilizar para recuperar al menos parte de la pérdida de rendimiento debido a la latencia no determinista del acceso a la memoria.
En realidad, la captación previa solo es rentable si realiza operaciones de transmisión (lectura de memoria de forma secuencial o altamente predecible).
(Dicho esto, si su código hace acceso frecuente a algunas áreas de memoria localizadas, el almacenamiento en caché ayudará).
Sin embargo, la mayoría del software de uso general debe hacer muchos accesos aleatorios a la memoria. Si consideramos los siguientes pasos:
Para la mayoría del software de propósito general, estos tres deben ejecutarse en rápida sucesión. En otras palabras, no siempre es posible (dentro de los límites de la lógica del software) calcular la dirección por adelantado, o encontrar suficiente trabajo para llenar los puestos entre estos tres pasos.
Para ayudar a explicar por qué no siempre es posible encontrar suficiente trabajo para llenar los puestos, así es como se puede visualizar.
(*) Si alguna vez pudiéramos hacer
NOP
un trabajo útil ...Las CPU modernas intentan hacer frente a lo mismo utilizando información dinámica, al mismo tiempo que siguen el progreso de cada instrucción a medida que circulan por las tuberías. Como mencioné anteriormente, parte de esa información dinámica se debe a una latencia de memoria no determinista, por lo tanto, los compiladores no pueden predecirla con ningún grado de precisión. En general, simplemente no hay suficiente información disponible en el momento de la compilación para tomar decisiones que podrían llenar esos puestos.
En respuesta a la respuesta de AProgrammer
No es que "compilar ... extraer paralelismo es difícil".
El reordenamiento de la memoria y las instrucciones aritméticas por parte de los compiladores modernos es la evidencia de que no tiene problemas para identificar operaciones que son independientes y, por lo tanto, ejecutables simultáneamente.
El principal problema es que la latencia de memoria no determinista significa que cualquier "emparejamiento de instrucciones" que uno haya codificado para el procesador VLIW / EPIC terminará estancado por el acceso a la memoria.
La optimización de las instrucciones que no se bloquean (solo registro, aritmética) no ayudará con los problemas de rendimiento causados por instrucciones que es muy probable que se bloqueen (acceso a la memoria).
Es un ejemplo de no aplicar la regla de optimización 80-20: optimizar las cosas que ya son rápidas no mejorará significativamente el rendimiento general, a menos que las cosas más lentas también se optimicen.
En respuesta a la respuesta de Basile Starynkevitch
No es "... (lo que sea) es difícil", es que EPIC no es adecuado para ninguna plataforma que tenga que hacer frente a un alto dinamismo en latencia.
Por ejemplo, si un procesador tiene todo lo siguiente:
Entonces VLIW / EPIC encajará bien.
¿Dónde se encuentran estos procesadores? DSP. Y aquí es donde ha florecido VLIW.
En retrospectiva, el fracaso de Itanium (y el continuo esfuerzo de I + D en un fracaso, a pesar de la evidencia obvia) es un ejemplo de fracaso organizacional y merece ser estudiado en profundidad.
Por supuesto, las otras empresas del proveedor, como hyperthreading, SIMD, etc., parecen tener mucho éxito. Es posible que la inversión en Itanium haya tenido un efecto enriquecedor en las habilidades de sus ingenieros, lo que les ha permitido crear la próxima generación de tecnología exitosa.
fuente
TL; DR: 1 / hay otros aspectos en la falla de Itanium que los problemas del compilador y pueden muy bien ser suficientes para explicarlo; El código de byte 2 / a no habría resuelto los problemas del compilador.
Bueno, también llegaron tarde (previsto para el 98, primer envío en 2001) y cuando finalmente entregaron el hardware, ni siquiera estoy seguro de que entregó lo prometido para la fecha anterior (IIRC, al menos dejaron caer parte del hardware). emulación x86 que se planeó inicialmente), por lo que no estoy seguro de que incluso si se hubieran resuelto los problemas de compilación (y AFAIK, todavía no se ha solucionado), habrían tenido éxito. El aspecto del compilador no fue el único aspecto demasiado ambicioso.
No estoy seguro de dónde colocar la herramienta.
Si está en el procesador, solo tiene otra microarquitectura y no hay razón para no usar x86 como ISA pública (al menos para Intel, la incompatibilidad tiene un costo más alto que lo que podría traer una ISA pública más limpia).
Si es externo, comenzar desde un código de bytes lo hace aún más difícil que comenzar desde un lenguaje de nivel superior. El problema con EPIC es que solo puede usar el paralelismo que puede encontrar un compilador, y extraer ese paralelismo es difícil. Conocer las reglas del idioma le brinda más posibilidades que si está limitado por algo ya programado. Mi recuerdo (no confiable y de alguien que lo siguió desde lejos) es que lo que HP (*) e Intel no lograron en el frente del compilador es la extracción del paralelismo a nivel de lenguaje, no el nivel bajo que habría estado presente en un byte código.
Quizás esté subestimando el costo al que el procesador actual logra su rendimiento. OOO es más efectivo que las otras posibilidades, pero seguramente no es eficiente. EPIC quería utilizar el presupuesto de área utilizado por la implementación de OOO para proporcionar más computación en bruto, con la esperanza de que los compiladores pudieran utilizarlo. Como se escribió anteriormente, no solo todavía no podemos, como AFAIK, incluso en teoría, escribir compiladores que tengan esa capacidad, sino que el Itanium tiene suficientes otras características difíciles de implementar que llegaron tarde y su potencia bruta no fue incluso competitivo (excepto quizás en algunos nichos de mercado con muchos cálculos de FP) con el otro procesador de gama alta cuando salió de fábrica.
(*) También parece subestimar el papel de HP en EPIC.
fuente
Unas pocas cosas.
IPF estaba en orden, por ejemplo. Esto significaba que no podía confiar en reordenar para salvarlo en caso de pérdida de caché u otro evento de larga duración. Como resultado, terminó necesitando depender de características especulativas, es decir, cargas especulativas (cargas que se les permitió fallar), útiles si no sabía si necesitaría un resultado de carga) y cargas avanzadas (cargas que podrían ser vuelva a ejecutar, usando el código de recuperación, si ocurriera un peligro.) Hacer esto bien fue difícil, especialmente las cargas avanzadas. También había sugerencias de captación previa de ramificaciones y caché que realmente solo podían ser utilizadas de manera inteligente por un programador de ensamblaje o mediante la optimización guiada por perfil, no generalmente con un compilador tradicional.
Otras máquinas en ese momento, a saber, UltraSPARC, estaban en orden, pero IPF también tenía otras consideraciones. Uno codificaba el espacio. Las instrucciones de Itanium, por naturaleza, no eran especialmente densas: un paquete de 128 bits contenía tres operaciones y un campo de plantilla de 5 bits, que describía las operaciones en el paquete y si podían emitirse todos juntos. Esto resultó en un tamaño efectivo de operación de 42.6 bits: compare con 32 bits para la mayoría de las operaciones comerciales de RISC en ese momento. (Esto fue antes de Thumb2, et al. RISC todavía significaba rigidez de longitud fija). Peor aún, no siempre tenía suficiente ILP para ajustarse a la plantilla que estaba usando, por lo que tendría que usar NOP-pad para completar el plantilla o el paquete. Esto, combinado con la relativa baja densidad existente, significaba que obtener una buena tasa de aciertos de i-cache era a) realmente importante,
Si bien siempre sentí que el argumento de "el compilador era el único problema" fue exagerado - hubo problemas legítimos de microarquitectura que realmente no favorecieron a I2 para el código de uso general - no fue especialmente divertido generar código en comparación a las máquinas OoO más estrechas y de mayor reloj del día. Cuando realmente podía llenarlo adecuadamente, lo que a menudo involucraba PGO o codificación manual, lo hizo muy bien, pero muchas veces, el rendimiento de los compiladores realmente no era inspirador. IPF no facilitó la generación de código excelente, y fue implacable cuando el código no era excelente.
fuente
Lo que describe es un poco lo que Transmeta intentó hacer con su software de transformación de código (que traducía dinámicamente x86 "bytecode" en el código interno de la máquina Transmeta).
En cuanto a por qué Intel no pudo hacer un compilador lo suficientemente bueno para IA64 ... Supongo que es que no tenían suficiente experiencia en compilación interna (incluso si, por supuesto, tenían algunos muy buenos expertos en compilación, pero probablemente no lo suficiente para hacer una masa crítica). Supongo que su administración subestimó los esfuerzos necesarios para hacer un compilador.
AFAIK, Intel EPIC falló porque la compilación para EPIC es realmente difícil, y también porque cuando la tecnología del compilador mejoró lenta y gradualmente, otros competidores también pudieron mejorar su compilador (por ejemplo, para AMD64), compartiendo algunos conocimientos del compilador.
Por cierto, me hubiera gustado que AMD64 hubiera sido un conjunto de instrucciones más RISCy. Podría haber sido algo de POWERPC64 (pero probablemente no fue por problemas de patentes, por las demandas de Microsoft en ese momento, etc.). La arquitectura del conjunto de instrucciones x86-64 realmente no es una arquitectura "muy buena" para el escritor del compilador (pero de alguna manera es "suficientemente buena").
Además, la arquitectura IA64 tiene algunas limitaciones fuertes, por ejemplo, las 3 instrucciones / palabra han sido buenas siempre que el procesador tuviera 3 unidades funcionales para procesarlas, pero una vez que Intel fue a los nuevos chips IA64, agregaron más unidades funcionales, y la instrucción el paralelismo de nivel fue una vez más difícil de lograr.
Quizás RISC-V (que es un ISA de código abierto) gradualmente tendrá éxito lo suficiente como para que sea competitivo para otros procesadores.
fuente
Como señaló Robert Munn, fue la falta de compatibilidad con versiones anteriores lo que mató al Itanium (y muchas otras "nuevas" tecnologías).
Si bien escribir un nuevo compilador podría haber sido difícil, solo necesita unos pocos. El compilador de CA que produce código optimizado es imprescindible; de lo contrario, no tendrá un sistema operativo utilizable. Necesita un compilador de C ++, Java, y dado que la base de usuarios principal sería Windows algún tipo de Visual Basic. Así que esto no fue realmente un problema. Había un sistema operativo decente (NT) y un buen compilador de C disponible.
Lo que parecería un esfuerzo trivial para una empresa que ofrece un producto de software: recompilar y volver a probar su base de código C (¡y en ese momento la mayoría habría sido escrita en C puro!) No era tan simple; La conversión de un gran conjunto de programas en C que asumían un número entero de 32 bits y asumían un direccionamiento de 32 bits a una arquitectura nativa de 64 bits estaba llena de dificultades. Si IA64 se hubiera convertido en un chip dominante (¡o incluso uno popular!), La mayoría de las compañías de software habrían mordido la bala y hecho el esfuerzo.
Chip tan rápido con un sistema operativo razonable pero un conjunto de software disponible muy limitado, por lo tanto, no muchas personas lo compraron, por lo tanto, no muchas compañías de software proporcionaron productos para él.
fuente
Lo que mató a Itanium fueron los retrasos en los envíos que abrieron la puerta para que AMD64 interviniera antes de que los proveedores de software se comprometieran a migrar a IA64 para aplicaciones de 64 bits.
Dejar la optimización al compilador fue una buena idea. Se pueden hacer muchas cosas estáticas que de otro modo serían ineficientes en el hardware. Los compiladores se volvieron bastante buenos en eso, especialmente cuando usé perfiles PGO (trabajé en HP y el compilador de HP tendió a superar a los de Intel). PGO fue difícil de vender, sin embargo, es un proceso difícil para el código de producción.
IPF estaba destinado a ser compatible con versiones anteriores, pero una vez que se lanzó AMD64 se convirtió en discutible, la batalla se perdió y creo que el hardware X86 en la CPU se despojó para volver a funcionar como CPU del servidor. Itanium como arquitectura no era malo, las 3 instrucciones por palabra no eran un problema. Lo que fue un problema es la implementación de hiperprocesos intercambiando pilas durante la memoria IO fue demasiado lenta (para vaciar y volver a cargar la tubería) hasta Montecito, etc., lo que evitó que compitiera con CPU PowerPC fuera de servicio. Los compiladores tuvieron que parchear fallas tardías en la detección de implementaciones de CPU, y parte de la ventaja del rendimiento se perdió por errores difíciles de predecir.
La arquitectura permitió que Itanium fuera relativamente simple al tiempo que proporcionaba herramientas para que el compilador obtuviera rendimiento de él. Si la plataforma hubiera vivido, las CPU se habrían vuelto más complejas y eventualmente se habrían enhebrado, fuera de servicio, etc., como x86. Sin embargo, los primeros gens enfocaron el conteo de transistores en otros esquemas de rendimiento ya que el compilador manejó muchas de las cosas difíciles.
La plataforma IPF apostó por el compilador y las herramientas, y fue la primera arquitectura en exponer un diseño de Unidad de Monitoreo de Desempeño (PMU) extremadamente completo y poderoso, que luego fue trasladado a Intel x86. Por lo tanto, los desarrolladores de herramientas potentes aún no lo utilizan en toda su capacidad para perfilar código.
Si observa los éxitos de ISA, a menudo no es el lado técnico el que tira los dados. Es su lugar en el tiempo y las fuerzas del mercado. Mire los SGI Mips, DEC Alpha ... Itanium solo fue respaldado por los perdedores, los servidores SGI y HP, empresas con gestiones que acumularon errores comerciales estratégicos. Microsoft nunca fue completo y abrazó a AMD64 para no ser incluido solo con Intel como jugador, e Intel no jugó bien con AMD para darles una forma de vivir en el ecosistema, ya que tenían la intención de acabar con AMD.
Si nos fijamos en dónde estamos hoy, el complejo hardware de X86 lo ha llevado a un callejón sin salida de la evolución hasta ahora. Estamos atascados a 3 + GHz, y volcamos los núcleos con un uso insuficiente. El diseño más simple de Itanium habría empujado más cosas en el compilador (espacio para el crecimiento), permitiendo construir tuberías más delgadas y rápidas. Con la misma generación y tecnología fabulosa, habría estado funcionando más rápido y limitado de todos modos, pero un poco más alto, con tal vez otras puertas para abrir para empujar la ley de Moore.
Bueno, al menos lo anterior son mis creencias :)
fuente
La memoria se está volviendo vaga ... Itanium tenía algunas ideas geniales que necesitarían un gran soporte de compilación. El problema era que no era una característica, eran muchas. Cada uno no era gran cosa, todos juntos sí.
Por ejemplo, había una característica de bucle donde una iteración del bucle funcionaría en registros de diferentes iteraciones. x86 maneja el mismo problema a través de una capacidad masiva fuera de servicio.
En ese momento, Java y JVM estaban de moda. Lo que IBM dijo fue que con PowerPC, podría compilar bytecode rápidamente y la CPU lo haría rápido. No en Itanium.
fuente