Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

238
Views
¿Los compiladores reducen funciones simples dados argumentos constantes en instrucciones únicas?

Esto es algo que siempre he pensado que es cierto, pero nunca he tenido ninguna validación. Considere una función muy simple:

 int subtractFive(int num) { return num -5; }

Si una llamada a esta función usa una constante de tiempo de compilación como

 getElement(5);

Es muy probable que un compilador con optimizaciones activadas alinee esto. Sin embargo, lo que no me queda claro es si el num - 5 se evaluará en tiempo de ejecución o en tiempo de compilación. ¿Se extenderá la simplificación de expresiones recursivamente a través de funciones en línea de esta manera? ¿O no trasciende funciones?

over 4 years ago · Santiago Trujillo
3 answers
Answer question

0

Simplemente podemos mirar el ensamblaje generado para averiguarlo. Este código:

 int subtractFive(int num) { return num -5; } int main(int argc, char *argv[]) { return subtractFive(argc); }

compilado con rendimientos de g++ -O2

 leal -5(%rdi), %eax ret

Entonces, la llamada a la función se redujo de hecho a una sola instrucción. Esta técnica de optimización se conoce como inline .

Por supuesto, uno puede usar la misma técnica para ver qué tan lejos llegará un compilador con eso, por ejemplo, el un poco más complicado

 int subtractFive(int num) { return num -5; } int foo(int i) { return subtractFive(i) * 5; } int main(int argc, char *argv[]) { return foo(argc); }

todavía se compila a

 leal -25(%rdi,%rdi,4), %eax ret

así que aquí ambas funciones fueron eliminadas en tiempo de compilación. Si la entrada a foo se conoce en el momento de la compilación, la llamada a la función (en este caso) simplemente se reemplazará por la constante resultante en el momento de la compilación ( Live ).

El compilador también puede combinar esta alineación con el plegado constante, para reemplazar la llamada a la función con su resultado completamente evaluado si todos los argumentos son constantes de tiempo de compilación. Por ejemplo,

 int subtractFive(int num) { return num -5; } int foo(int i) { return subtractFive(i) * 5; } int main() { return foo(7); }

compila a

 mov eax, 10 ret

que es equivalente a

 int main () { return 10; }

Un compilador siempre hará esto cuando crea que es una buena idea, y (por lo general) es mucho mejor que usted para optimizar el código en este nivel bajo.

over 4 years ago · Santiago Trujillo Report

0

Es fácil hacer una pequeña prueba; considera lo siguiente

 int foo(int); int bar(int x) { return x-5; } int baz() { return foo(bar(5)); }

Al compilar con g++ -O3 , la salida de asm para la función baz es

 xorl %edi, %edi jmp _Z3fooi

Este código carga un 0 en el primer parámetro y luego salta al código de foo . Entonces, el código de la barra desapareció por completo y el cálculo del valor para pasar a foo se realizó en tiempo de compilación.

Además, devolver el valor de llamar a la función se convirtió en solo un salto al código de función (esto se llama "optimización de llamada de cola").

over 4 years ago · Santiago Trujillo Report

0

Un compilador inteligente evaluará esto en el momento de la compilación y reemplazará getElement(5) porque nunca tendrá un resultado diferente. Ninguna de las variables se considera volátil.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!