PARALELISMO VIA CPUS MULTIHILOS Y MULTINUCLEOS Introducción Son tecnologías que permiten mejorar el rendimiento de las CPUs. Ambos diseños soportan multiprogramación (multitasking) vía programas paralelos ó corriendo aplicaciones concurrentemente. Primero fueron diseñados los CPUs multihilos que utilizan un contexto a nivel de hardware alternando entre hilos, para reducir el tiempo de los recursos. Poco después se diseñaron CPUs que integraban más de un núcleo en un único chip. Hoy en día tenemos procesadores de hasta 8 núcleos. Espectro de diseño Tanto los CPUs multihilos, como los multinúcleo, explotan concurrencia ejecutando múltiples hilos, aunque sus objetivos de diseño son distintos. Los CPUs multihilos soportan hilos ejecutados concurrentemente, pero lo hacen a nivel de instrucción, apuntando a una mejor utilización de la CPU, planteando instrucciones desde múltiples hilos. Los CPUs multinúcleo alcanzan la concurrencia de hilos a un nivel más alto concentrándose menos en la utilización por núcleo y apuntando a la escalabilidad vía replicación de núcleos. Núcleos Multihilos Los núcleos multihilo ejecutan de manera concurrente múltiples hilos de procesamiento, de uno o varios programas. Cada hilo sobre el chip necesita su única componente de estado como instruction pointer y registros de control. El número de hilos sobre el chip determina el número de replicaciones necesarias de componentes de estado y el máximo grado de concurrencia soportado por hardware y saturación por unidades de ejecución. Mas hilos también mejoran las posibilidades de esconder latencias de memoria de acceso (memory acces latency) o stall por malas predicciones de rama. El crecimiento del costo es aproximadamente lineal hasta al menos 8 hilos, pero es claramente superlineal de ahí en adelante. El número de hilos sobre el chip por núcleo típicamente soportado por un procesador comercial tiene un rango desde 2 en Intel Xeon hasta 8 en Suns UltraSPARC T2. La mayoría de los cpus emplean el último enfoque llamado Simultaneous Multithreading (SMT) y que Intel lo llama Hyperthreading Technology (HTT). El SMT ejecuta instrucciones de varios hilos distintos en un mismo ciclo de reloj, usando un único procesador. CPUs Multinucleo Los núcleos Multihilos tienen una limitada escalabilidad, atado por el punto de saturación de las unidades de ejecución y el costo de hilos adicionales. En cambio los CPU’s multinúcleos prometen mas potencia por escalabilidad. Los primeros chips multicore fueron construidos como una simple unión de diseños de CPU’s de un solo núcleo ya existentes. Estos chips retuvieron mucha de la arquitectura de su precedente, replicando solo el control y unidades de ejecución y compartiendo las unidades faltando por chip: cache, controlador de memoria, unidades de procesamiento secundarias como unidades de punto flotante (FPUS, componentes de enfriamiento y pines de salida del micro. Sin embargo, tienen una desventaja en relación con el intercambio de contención de los recursos compartidos. Las tendencias de desarrollo indican un movimiento hacia la replicacion adicional sobre los componentes de chips, como los controladores de memoria y cache, que pueden ser privadas o compartidas. Cache compartido vs. Cache privado CACHE: es un conjunto de datos duplicados de otros originales, con la propiedad de que los datos originales son costosos de acceder, normalmente en tiempo, respecto a la copia en caché. La primera vez que se accede al dato, se hace una copia en el caché y los accesos siguientes al dato se hacen sobre esta copia. Con lo que se obtiene menor tiempo de acceso medio al dato. El rasgo mas importante para mejorar la performance de las CPUS es la concurrencia. El segundo rasgo mas importante es el caché. Debido a que las velocidades de los micros son muy superiores a los tiempos de acceso a una memoria, se crea una brecha. Para mitigar esto, se explota el espacio disponible en chip para poner mas memorias de caché. Algunos CPUS optan por caminos totalmente diferentes, poniendo nada de cache y escondiendo las latencias de memorias mediante multithreading o usando memorias de direccionamiento de alta velocidad. La mayoría de los CPUS multinucleos utilizan un cache L1 privado por núcleo para reducir la contención para este nivel de cache critico. CONTENCION de un recurso es la competencia de usuarios por un recurso del sistema al mismo tiempo. Entonces, por cada núcleo, un cache L1 privado. Si el núcleo tiene multihilo, el cache L1 se comparte entre los hilos del núcleo. Además, tienen un cache L2 que puede ser privado y dedicado a cada núcleo o compartido entre varios núcleos. El cache L3 históricamente estuvo fuera del chip y compartido pero en la actualidad algunos CPUS lo ponen sobre el chip. Si el cache compartido o privado es mas beneficioso depende de la utilización del espacio del chip, y las características de la aplicación. Caches compartidos son importantes si los hilos de la misma aplicación se ejecutan en múltiples núcleos y comparten una cantidad significante de información. En estos casos es más económico, evita múltiples copias de la información y transferencias de cache a cache. La desventaja es que puede imponer altas demandas de interconexión. Si los hilos no comparten mucha información pueden COMPETIR por el cache. Esto hace difícil predecir el servicio a cada hilo ya que depende de patrones de memoria, carga total del sistema, etc. Los caches privados son una solución fácil para aislar el desempeño y garantizar un servicio predecible. Hay una opción más flexible: el diseño hibrido. Diferentes números de bancos de cache que pueden ser COMPARTIDOS o PRIVADOS, dependiendo de las necesidades de los hilos corriendo en el momento en el sistema. Este diseño soporta hilos que comparten información y que no. Recursos compartidos vs. Recursos privados A diferencia de los diseños multinucleos que tienden a replicar la mayor cantidad de recursos, COMPARTIR RECURSOS es la opción predominante en el multithreading de hardware. De todos modos, algún nivel de replicación y partición es necesario. Replicación es esencial para unidades de ejecución que puedan ser sujetas a altas contenciones. Partición estática o dinámica de recursos para garantizar a cada hilo acceso exclusivo a su parte. Es una solución para proveer progreso justo e independiente a la ejecución de cada hilo. Compartir permite más flexibilidad en el uso de recursos. Tolerancia a fallas Fallas: Ruido Eléctrico. Defectos menores permanentes en el silicio (Fallas en componentes individuales) que se expanden provocando la falla del chip entero. Soluciones: Particionamiento de unidades replicadas y separables. Múltiples interconexiones dentro del chip. Controladores de memoria. Múltiples bancos de cache. Esto lleva a soportar diferentes grados de aislación contra compartición y separación de componentes que funcionan de los que no funcionan. Estas soluciones incrementan mucho la tolerancia a fallos. Interconexiones Otro rasgo importante que impacta en el performance de los chips multinúcleos es la comunicación entre los diferentes componentes sobre el chip: núcleos, cache, y -si están integradoscontroladores de memoria y controladores de red. Los primeros diseños usaban un bus como en los sistemas tradiciones de múltiples CPU. La tendencia ahora cambio a una Crossbar u otros mecanismos avanzados para reducir latencias y contención. Por ejemplo, los CPUS de AMD emplean una Crossbar, y el TileraTILE64 implementa “Non-blocking multilink mesh”. La interconexión se puede volver cara. Una Crossbar de 8x8 sobre el chip puede consumir tanta área como cinco núcleos y tanta energía como dos núcleos. En caches privados en el chip, el intercambio de datos entre hilos corriendo en diferentes núcleos necesitó usar la conexión fuera del chip. Caches compartidos sobre el chip naturalmente soportan intercambio de información entre hilos corriendo en diferentes núcleos. Así, introduciendo un nivel de cache compartido en el chip (comúnmente L2, o en las tendencias mas recientes L3) ayudaron a reducir trafico fuera del chip. A medida que el procesamiento de datos aumenta con mas hilos paralelos, demanda además un incremento en la comunicación fuera del chip para: acceso a memoria, entrada/salido o comunicación CPU-a-CPU. Para direccionar estos requerimientos, la comunicación fuera del chip esta tendiendo de “basada-en-bus” a “basada-en-paquetes”, interconexiones punto-a-punto. AMD implemento este concepto por primera vez como HyperTransport, seguido por las interconexiones de Intel's QuickPath. Diseños especializados Algunos procesadores multinucleos están hechos para cargas de trabajo muy específicas. La serie Blue Vega de aplicación de cómputo usa chips multinucleos con hasta 48 núcleos, cada uno incluyendo unidades especiales de ejecución diseñadas para incrementar el desempeño de operaciones Java. El Tilera TILE64 para procesamiento de información usa 64 núcleos simples de bajo consumo, su capacidad de dataflow lo hace una buena elección para sistemas embebidos. Los GPUS (graphic processing units) representan el ejemplo extremo de diseño multinucleo especializado. Los GPUS modernos tienen 10 o mas núcleos, cada uno optimizado para procesamiento de data SIMD (Single Instruction-Multiple Data), hecho vía cientos o miles de hilos simplificados por núcleo. Esto los hace útiles para complicados procesos numéricos como rendering de video, estudios de genética, modelado científico o criptografía. Complejidad de núcleos vs. Numero de núcleos Optimización Tradicional Incrementar velocidad de Ejecución serie de un único hilo Ejecución fuera de orden Relojes más rápidos Predicción dinámica de lazos La disponibilidad del paralelismo a nivel de hilo e instrucción es la decisión más importante para simplificar diseños tradicionales de CPUs y permitir mayor parte del circuito a la concurrencia. Otros chips incrementan la complejidad para maximizar el desempeño por núcleo. Los CPUS que se concentran en desempeño por hilo generalmente tienen relojes de más alta frecuencia que aquellos que se concentran en soporte para muchos hilos. El uso del espacio extra del chip para mejorar el desempeño de cada hilo produce ganancias no lineales (El desempeño se duplica cuando la complejidad se cuadruplica). Desempeño Por aplicación Los programas secuenciales no pueden explotar la concurrencia del chip. En programas paralelos, algunas partes del algoritmo se deben correr secuencialmente. Conclusiones: Mayor número de núcleos simples es preferible mientras la parte secuencial de la aplicación sea pequeña, sino son más beneficiosos los núcleos más complejos. Debido a la demanda de espacio en el chip para interconexiones entre gran numero de núcleos y a la escalabilidad limitada de aplicaciones puede resultar más beneficioso utilizar núcleos más complejos. Las aplicaciones que pueden explotar mucho del pico teórico de desempeño (intensivas en punto flotante, alto paralelismo de instrucciones en aplicaciones numéricas) pueden tener mejores resultados si se usan núcleos más complejos. Una mejora para el desempeño por hilo seria colocar más recursos del chip dinámicamente, como ejecución especulativa. Esto beneficia aplicaciones con mucha dependencia de datos y errores de cache. Una implementación ya aplicada en algunos CPUs multihilos coloca recursos particionados a un hilo si se corre en modo “Única Tarea”. La investigación indica que los procesadores que poseen muchos núcleos simples y unos pocos núcleos de alto rendimiento pueden proveer el mayor poder de procesamiento para un dado espacio de chip y presupuesto energético. Pero esto tiene como desventaja que dichos procesadores no se obtienen comercialmente, y además, son difíciles de diseñar y programar. Costo y consumo de energía La performance no domina más los objetivos de diseño: Los costos de fabricación de chips y la tolerancia a falla, consumo de energía y disipación de calor se volvieron consideraciones críticas. A medida que los núcleos se simplifican, el consumo de energía disminuye linealmente, lo cual es una gran ventaja en CPUS multinúcleos. Una mejor eficiencia de energía y una generación de calor reducida permiten integraciones de más núcleos en un único CPU, con el cambio (tradeoff) que el presupuesto de energía para las interconexiones incrementa con el número de núcleos. El uso de energía afecta la elección entre diseños multinúcleos y diseños de un núcleo Multihilo. Los primeros son eficientes con respecto a la energía, pero diseños híbridos con múltiples núcleos SMT logran casi el mismo performance por watt como diseños puro CMP (Chip-level MultiProcessing). A pesar de que el CPU consume el 25 a 45% de la energía que consume un servidor, los costos proyectados de electricidad para un término de cuatros años se acercan al precio del sistema entero. En el caso de maquinas de alto-performance de computo, construyendo soluciones de enfriamiento personalizadas puede costar tanto como la computadora misma. Además, la reducción de consumo de energía permite mayor densidad de racks en habitaciones de servidores. El desafío del software En el futuro, la tendencia dice que habrá CPUS de cada vez más hilos y más núcleos. Sin embargo, la concurrencia de hardware solo puede ser explotada con múltiples programas seriales o con aplicaciones en paralelos. Hay limites para mejorar el desempeño por hilo ya que las instrucciones seriales deben ejecutarse una tras otra, por lo tanto el código serial debe ser cuidadosamente optimizado. La mayor parte de los softwares no esta preparado para la concurrencia. Las posibilidades para extraer paralelismo automáticamente están limitadas y el paralelismo debe ser expresado explícitamente. Herb Sutter considera que cambiar hacia programación paralela sea la próxima revolución después de la introducción de programación orientada a objetos. Escribiendo correcta y eficientemente programas paralelos es un gran desafío que requiere mejores herramientas y modelos de programación más abstractos para hacer la programación de hilos más segura y conveniente. Incluso si la información puede ser compartida, muchos programadores usan exclusivamente procesos sin que importen los beneficios de usar softwares multithreaded en memoria compartida de nodos simétricos multiprocesales. Los clusters HPC con nodos de muchos núcleos pueden requerir el uso de programación de hilos/modelos de procesos híbridos para mayor eficiencia y escalabilidad. Las aplicaciones HPC van a necesitar mostrar un grado mayor de paralelismo que antes para explotar la concurrencia de hardware ofrecidos por los CPUS multinucleos. Un factor limitante es que el desempeño de núcleos adicionales es menor que el de CPUS adicionales, excepto cuando los hilos comparten información. Sobre los sistemas operativos: los organizadores (schedulers) de los CPUS tradicionales necesitaron modificaciones para acomodar la heterogeneidad y diferencias de desempeño en la jerarquía de CPUS, núcleos e hilos de hardware. Schedulin con el objetivo de minimizar la contención de recursos es importante si la maquina esta con carga total. Dirección propuesta para CPUs multihilos y multinucleos. Según la ley de Moore, los diseños de chips van a crecer a grandes números de núcleos e hilos de hardware. Sin embargo las comunicaciones fuera del chip y los límites de pines ponen restricciones significantes en la escalabilidad y programabilidad de los chips, ya que impactan en la tasa de transferencia de datos desde y hacia los núcleos. Para computación común se opta por diseños híbridos. Un bajo nº de hilos sobre un chip puede añadirse por relativamente poca circuitería adicional y pueden incrementar significativamente el Througput. Así el espacio del chip es generalmente mejor explotado para más núcleos, cache u otros componentes. Con respecto a los límites de software, pocas aplicaciones pueden usar muy alta concurrencia para incrementos en el performance. El éxito de diseños de multinucleos depende altamente de que existan las herramientas de programación correcta, librerías y modelos. Los cpus actuales en el mercado, ofrecen diferentes opciones de acuerdo a su diseño y uso del espacio del chip. Consideraciones de diseño NO solo incluyen el número de núcleos e hilos sino también la complejidad de los núcleos, interconexiones, tamaños de cache y el grado en que los componentes se comparten. Ya que las decisiones de diseño incluyen cambios (algo por algo, no puedo mejorar algo sin descuidar otra cosa) son necesarios diseños que se concentren en la relación funcional entre las partes y el todo, llevados por las aplicaciones de destino y criterios adicionales de optimización como la consumición de energía, la disipación de calor, tolerancia a falla y costo NOTA: Se llama throughput al volumen de información que fluye a través de un sistema.