¿Hay algún cambio que se pueda hacer en las CPU para que funcionen mejor en tiempos de ejecución concurrentes como Rust? Por ejemplo, ¿hay cambios en las implementaciones de predicción de sucursales o en los tamaños de caché que ayudarían a los tiempos de ejecución concurrentes?
Tengo la impresión de que los diseños actuales de CPU podrían optimizarse más para tiempos de ejecución de procedimiento como C. Si en lugar de eso optimizáramos para tiempos de ejecución concurrentes, ¿cómo se verían diferentes las CPU?
Por ejemplo, la predicción de rama se implementó en base a generalizaciones dibujadas en trabajos de investigación que analizan códigos de procedimiento. Me pregunto si la abstracción de concurrencia agregará un conjunto de trabajo significativo al tiempo de ejecución que afecta negativamente a los algoritmos de predicción de rama existentes. Por ejemplo, predecir en un bucle for es una cosa, pero cuando el objetivo de la rama siempre es una nueva porción de memoria (gráfico, texto, etc.), siempre será una falta de caché, y nunca habrá una rama historia para ello, porque ninguno lo ha tocado todavía.
Esta es probablemente una pregunta tonta porque el contenido, aunque siempre puede estar en RAM, se ramificará a un orden de magnitud menor de lo que se usará (una vez que se haya cargado en la memoria caché) ... pero aún así, allí debería ser un límite temporal observable para los contextos almacenados en la memoria caché y los predictores de ramificación en un tiempo de ejecución de procedimiento, que se manifestaría como un límite de abstracción en un entorno más paralelo. Entonces me pregunto ... ¿Se han observado estos límites? ¿Algún trabajo de investigación ha analizado esto?
¿Las arquitecturas de la CPU están sesgadas hacia el código de procedimiento sobre el código concurrente; ¿O son las CPU modernas lo suficientemente generales para que un lenguaje altamente concurrente no sufra?
Respuestas:
Probablemente sea más el caso que las arquitecturas informáticas modernas están diseñadas con el objetivo de mejorar la calidad del código generado por los compiladores contra un presupuesto de costo en el área y la potencia utilizada. Las bibliotecas de tiempo de ejecución son solo una instancia específica de código compilado que debe ejecutarse de manera eficiente.
Durante mucho tiempo, el lenguaje de destino para la mayoría de las arquitecturas ha sido el lenguaje "C". Esto refleja las demandas modestas que ese lenguaje hace en su hardware y el hecho de que se ha convertido en un lenguaje de programación de sistemas casi universal (lo siento, Rust and Go, tienes un largo camino por recorrer para vencer a C).
Una consecuencia de esto parece ser que los nuevos lenguajes a menudo se definen en términos de su semántica equivalente en C solo para que eviten la necesidad de instalaciones de procesador que probablemente estén ausentes en las computadoras actuales.
La recompensa para un procesador que combina bien con los compiladores modernos es que el código de esos compiladores funciona bien y el procesador tiene al menos la oportunidad de ser competitivo. El costo de la falla aquí condena al procesador antes de que pueda comenzar. Solo dos ejemplos negativos incluyen el iAPX-432 y el Itanium, ambos de Intel. Ambos tenían una relación muy pobre con sus compiladores (Ada y C respectivamente) con el fracaso de los productos convirtiéndose en un juego de culpa entre el silicio y el software.
fuente
Sin duda sí.
En particular, el modelo de comunicaciones implicado por C99 es memoria compartida. Los lenguajes concurrentes más avanzados tienen modelos de comunicación más ricos, como canales de paso de mensajes (como en Rust).
Las arquitecturas de CPU modernas tienen soporte de hardware explícito para memoria compartida. En particular, los protocolos de coherencia de caché como MESI se implementan en puertas y cables reales. No existe un soporte real para el paso de mensajes entre procesos, a pesar de que la idea del paso de mensajes no es ajena a la CPU. ¡Los buses PCI-e modernos incluso emulan la memoria compartida usando el paso de mensajes, mientras que los procesos de la CPU tienen que emular el paso de mensajes usando la memoria compartida!
fuente