Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

165
Vistas
¿Por qué el mismo código ensamblador generado no conduce a la misma salida?

Código de muestra ( t0.c ):

 #include <stdio.h> float f(float a, float b, float c) __attribute__((noinline)); float f(float a, float b, float c) { return a * c + b * c; } int main(void) { void* p = V; printf("%a\n", f(4476.0f, 20439.0f, 4915.0f)); return 0; }

Invocación y ejecución (a través de godbolt.org):

 # icc 2021.1.2 on Linux on x86-64 $ icc t0.c -fp-model=fast -O3 -DV=f 0x1.d32322p+26 $ icc t0.c -fp-model=fast -O3 -DV=0 0x1.d32324p+26

El código ensamblador generado es el mismo: https://godbolt.org/z/osra5jfYY .

¿Por qué el mismo código ensamblador generado no conduce a la misma salida?

¿Por qué void* p = f; ¿materia?

over 4 years ago · Santiago Trujillo
1 Respuestas
Responde la pregunta

0

Godbolt le muestra el ensamblaje emitido al ejecutar el compilador con -S . Pero en este caso, ese no es el código que realmente se ejecuta, porque se pueden realizar más optimizaciones en el momento del enlace.

Intente marcar la casilla "Compilar en binario" en su lugar ( https://godbolt.org/z/ETznv9qP4 ), que en realidad compilará y vinculará el binario y luego lo desensamblará. Vemos que en su versión -DV=f , el código para f es:

 addss xmm0,xmm1 mulss xmm0,xmm2 ret

como antes Pero con -DV=0 , tenemos:

 movss xmm0,DWORD PTR [rip+0x2d88] ret

Entonces f se ha convertido en una función que simplemente devuelve una constante cargada desde la memoria. En el momento del enlace, el compilador pudo ver que f solo se llamaba con un conjunto particular de argumentos constantes, por lo que podía realizar una propagación constante entre procedimientos y hacer que f simplemente devolviera el resultado precalculado.

Tener una referencia adicional a f evidentemente derrota esto. Probablemente el compilador o el enlazador ve que se tomó la dirección de f y no se dio cuenta de que nunca se hizo nada con la dirección. Por lo tanto, asume que f podría llamarse en otra parte del programa y, por lo tanto, tiene que emitir un código que dé el resultado correcto para argumentos arbitrarios.

En cuanto a por qué los resultados son diferentes: el precálculo se realiza estrictamente, evaluando tanto a*c como b*c como float y luego añadiéndolos. Entonces, su resultado de 122457232 es el "correcto" según las reglas de C, y también es lo que obtiene al compilar con -O0 o -fp-model=strict . La versión de tiempo de ejecución se ha optimizado a (a+b)*c , que en realidad es más precisa porque evita un redondeo adicional; produce 122457224 , que está más cerca del valor exacto de 122457225 .

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda