es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Por qué el compilador no puede crear una pequeña tabla de saltos en lugar de una rama?

Esta es probablemente una pregunta estúpida, hecha por ignorancia.

Aquí hay un enlace que describe la predicción de ramificación. Dado que parece que esto no sería eficiente en CPUs tontas, ¿por qué el compilador no podría generar simplemente una tabla de saltos de dos elementos? Echa un vistazo al siguiente código:

int main(){
    bool c = true;
    if(c);        /* hacer algo aquí.      */
    else;         /* hacer algo más aquí. */
}

Con el explorador de compiladores, esto genera el siguiente código de máquina (-O0):

main:                                   # @main
        push    rbp
        mov     rbp, rsp
        mov     dword ptr [rbp - 4], 0
        mov     byte ptr [rbp - 5], 1
        test    byte ptr [rbp - 5], 1
        je      .LBB0_2
        jmp     .LBB0_3
.LBB0_2:
        jmp     .LBB0_3
.LBB0_3:
        mov     eax, dword ptr [rbp - 4]
        pop     rbp
        ret

Esto, por supuesto, tiene una rama, mientras que el siguiente código:

int main(){
    bool c = true;
    using jmptable_t = void(*)();
    jmptable_t jmptable[2] = {nullptr, nullptr};
    jmptable[c];
}

genera:

main:                                   # @main
        push    rbp
        mov     rbp, rsp
        sub     rsp, 32
        mov     byte ptr [rbp - 1], 1
        lea     rdi, [rbp - 32]
        xor     esi, esi
        mov     edx, 16
        call    memset@PLT
        xor     eax, eax
        add     rsp, 32
        pop     rbp
        ret

La mayoría de esto se generó para configurar la tabla de saltos. No hay ramas aquí.
Aquí, comparo la velocidad de los dos enfoques con -O0. La tabla de saltos fue consistentemente más rápida que la declaración if, lo cual me sorprendió porque pensé que la tabla de saltos sería menos optimizada.

¿Quizás mi prueba fue inexacta?

Preguntas:

  • ¿Cuál es más rápido en entornos generales, donde es probable que la optimización sea O1 o O2?
  • Cuando aumenté la optimización a O3, la declaración if se volvió drásticamente más rápida. ¿Por qué sucede esto? ¿Qué optimizaciones hizo el compilador?
Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    En primer lugar, es importante destacar que no hay preguntas estúpidas cuando se trata de aprender.

    Para responder a tu pregunta, una tabla de saltos puede ser más rápida que la predicción de ramificaciones en ciertos escenarios, especialmente cuando se trata de un pequeño número de posibles ramas. En el ejemplo que proporcionaste, donde solo hay dos ramas posibles, es probable que una tabla de saltos sea más rápida ya que elimina la necesidad de que la CPU prediga qué rama se tomará.

    Sin embargo, a medida que aumenta el número de ramas, los beneficios de una tabla de saltos disminuyen y la predicción de ramificación se vuelve más eficiente. Además, el tamaño de la tabla de saltos puede ser una preocupación ya que puede ocupar una cantidad significativa de memoria.

    En cuanto a los niveles de optimización, los resultados pueden variar dependiendo del escenario específico y las técnicas de optimización utilizadas por el compilador. En general, los niveles de optimización más altos probablemente resulten en un código más rápido, independientemente de si se utiliza una tabla de saltos o una predicción de ramificación. La razón por la cual la declaración if se volvió drásticamente más rápida con la optimización O3 es porque el compilador pudo realizar varias optimizaciones adicionales, como la expansión de funciones, el desenrollado de bucles y la eliminación de código muerto, lo que redujo aún más el tiempo de ejecución del código.

    Siempre es una buena idea probar y comparar diferentes técnicas de optimización para determinar qué enfoque es el mejor para un escenario específico.

Comments are closed.