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é los compiladores modernos no fusionan los accesos a memoria vecinos?

Considere el siguiente código:

bool AllZeroes(const char buf[4])
{
    return buf[0] == 0 &&
           buf[1] == 0 &&
           buf[2] == 0 &&
           buf[3] == 0;
}

Salida del ensamblador de Clang 13 con -O3:

AllZeroes(char const*):                        # @AllZeroes(char const*)
        cmp     byte ptr [rdi], 0
        je      .LBB0_2
        xor     eax, eax
        ret
.LBB0_2:
        cmp     byte ptr [rdi + 1], 0
        je      .LBB0_4
        xor     eax, eax
        ret
.LBB0_4:
        cmp     byte ptr [rdi + 2], 0
        je      .LBB0_6
        xor     eax, eax
        ret
.LBB0_6:
        cmp     byte ptr [rdi + 3], 0
        sete    al
        ret

Cada byte se compara individualmente, pero podría haberse optimizado en una sola comparación de enteros de 32 bits:

bool AllZeroes(const char buf[4])
{
    return *(int*)buf == 0;
}

Resultando en:

AllZeroes2(char const*):                      # @AllZeroes2(char const*)
        cmp     dword ptr [rdi], 0
        sete    al
        ret

También he comprobado GCC y MSVC, y ninguno de ellos hace esta optimización. ¿Está esto prohibido por la especificación de C++?

Edición:
Cambiar el AND de circuito corto (&&) por un AND a nivel de bits (&) generará el código optimizado. Además, cambiar el orden en que se comparan los bytes no afecta a la generación de código: https://godbolt.org/z/Y7TcG93sP

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    La optimización de comparar los 4 bytes a la vez usando una comparación de int de 32 bits no está prohibida por la especificación de C++. Sin embargo, en este caso específico, el operador AND cortocircuitado (&&) está impidiendo al compilador hacer esta optimización. Cambiar el AND cortocircuitado por un AND a nivel de bits (&) permitirá al compilador generar el código optimizado. Además, cambiar el orden en el que se comparan los bytes no afecta al código generado.

Comments are closed.