¿Por qué es lenta la instrucción de una rama de CPU?


Desde que empecé a programar, he leído en todos los lugares para evitar ramas derrochadoras a toda costa.

Eso está bien, aunque ninguno de los artículos explicaba por qué debería hacer esto. ¿Qué sucede exactamente cuando la CPU decodifica una instrucción de rama y decide hacer un salto? ¿Y cuál es la "cosa" que lo hace más lento que otras instrucciones (como la adición)?

Author: Peter Mortensen, 2012-03-22

3 answers

Una instrucción de rama no es inherentemente más lenta que cualquier otra instrucción.

Sin embargo, la razón por la que escuchó que las ramas deben evitarse es porque las CPU modernas siguen una arquitectura de tuberías. Esto significa que hay varias instrucciones secuenciales que se ejecutan simultáneamente. Pero la tubería solo se puede utilizar completamente si es capaz de leer la siguiente instrucción de memoria en cada ciclo, lo que a su vez significa que necesita saber qué instrucción Leer.

En una rama condicional, generalmente no sabe de antemano qué camino se tomará. Así que cuando esto sucede, la CPU tiene que detenerse hasta que la decisión se ha resuelto, y tira todo en la tubería que está detrás de la instrucción de la rama. Esto reduce la utilización y, por lo tanto, el rendimiento.

Esta es la razón por la que las cosas como rama de predicción de y branch delay slots existen.

 42
Author: Oliver Charlesworth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-22 10:47:28

Debido a que la CPU adopta la canalización para ejecutar instrucciones, lo que significa que cuando una instrucción anterior se está ejecutando en alguna etapa (por ejemplo, leyendo valores de registros), la siguiente instrucción se ejecutará al mismo tiempo, pero en otra etapa (por ejemplo, la etapa de decodificación). Está bien para instrucciones que no son de control, pero complica las cosas cuando se ejecutan instrucciones de control como jmp o call.

Dado que la CPU no sabe qué instrucción siguiente será al ejecutar un jmp instrucción, utiliza predicción de rama técnicas para predecir si la instrucción de rama será tomada o no (Por ejemplo, una instrucción de rama en un fragmento de bucle probablemente llevará el flujo de instrucción de vuelta a la cabeza del bucle).

Sin embargo, cuando dicha predicción falla, lo que se denomina predicción errónea de rama, afectará el rendimiento de la ejecución. Desde la tubería después de la rama tiene que ser descartado, y empezar de nuevo desde la instrucción correcta.

 6
Author: ZelluX,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-22 10:32:10

Oli dio una muy buena explicación de por qué la ramificación es costosa: la predicción de oleoductos y ramificaciones. Sin embargo, quiero agregar que no debería estar muy preocupado por el problema, ya que los compiladores modernos optimizarán el código y una optimización es reducir la ramificación.

Puede leer más sobre las optimizaciones de C++ en el compilador de Microsoft aquí - el Optimizador guiado por perfiles utiliza información de tiempo de ejecución (es decir, qué partes del código se utilizan más) para optimizar su código. La aceleración es en el rango del 20%.

Una de las operaciones es "Optimización de Rama Condicional", por ejemplo - suponiendo que la mayor parte del tiempo i es 6-esto es más rápido:

if (i==6)
{
    //...
}

else
{
    switch (i)
    {
        case 1: //
        case 2: //
        //...
    }
}

Que:

switch (i)
{
    case 1: //
    //...
    case 6: //
    case 7: //
}

Aquí hay una entrada de blog sobre otras optimizaciones: http://bogdangavril.wordpress.com/2011/11/02/optimizating-your-native-program /

 3
Author: Bogdan Gavril MSFT,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-22 10:40:28