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

442
Views
¿Por qué los compiladores insisten en usar un registro guardado por destinatario aquí?

Considere este código C:

 void foo(void); long bar(long x) { foo(); return x; }

Cuando lo compilo en GCC 9.3 con -O3 o -Os , obtengo esto:

 bar: push r12 mov r12, rdi call foo mov rax, r12 pop r12 ret

La salida de clang es idéntica excepto por la elección de rbx en lugar de r12 como el registro guardado por la persona que llama.

Sin embargo, quiero/espero ver un ensamblaje que se parezca más a esto:

 bar: push rdi call foo pop rax ret

Dado que tiene que empujar algo a la pila de todos modos, parece más corto, más simple y probablemente más rápido simplemente empujar su valor allí, en lugar de empujar el valor de un registro arbitrario guardado por la persona que llama allí y luego almacenar su valor en ese registro. Lo mismo ocurre con el inverso después de call foo cuando estás volviendo a colocar las cosas.

¿Está mal mi montaje? ¿Es de alguna manera menos eficiente que jugar con un registro adicional? Si la respuesta a ambas es "no", entonces ¿por qué GCC o Clang no lo hacen de esta manera?

Enlace de Godbolt .


Editar: aquí hay un ejemplo menos trivial, para mostrar que sucede incluso si la variable se usa de manera significativa:

 long foo(long); long bar(long x) { return foo(x * x) - x; }

Entiendo esto:

 bar: push rbx mov rbx, rdi imul rdi, rdi call foo sub rax, rbx pop rbx ret

Prefiero tener esto:

 bar: push rdi imul rdi, rdi call foo pop rdi sub rax, rdi ret

Esta vez, es solo una instrucción frente a dos, pero el concepto central es el mismo.

Enlace de Godbolt .

over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

¿Por qué los compiladores insisten en usar un registro guardado por destinatario aquí?

Porque la mayoría de los compiladores generarían casi el mismo código para una función determinada y siguen convenciones de llamadas globales definidas por la ABI objetivo de su compilador.

Puede definir sus propias convenciones de llamada diferentes (por ejemplo, pasar incluso más argumentos de función en los registros del procesador o, por el contrario, "empaquetar" mediante operaciones bit a bit dos argumentos short en un solo registro del procesador, etc.), e implementar su compilador siguiéndolos . Probablemente necesite volver a codificar parte de la biblioteca estándar de C (por ejemplo, parchear las partes inferiores de GNU libc y luego volver a compilarla, si está en Linux).

IIRC, algunas convenciones de llamadas son diferentes en Windows y en FreeBSD y en Linux para la misma CPU.

Tenga en cuenta que con un GCC reciente (por ejemplo, GCC 10 a principios de 2021) podría compilar y vincular con gcc -O3 -flto -fwhole-program y, en algunos casos, obtener alguna expansión en línea . También puede compilar GCC a partir de su código fuente como un compilador cruzado , y dado que GCC es un software gratuito , puede mejorarlo para que siga sus nuevas convenciones de llamadas privadas. Asegúrese de documentar primero sus convenciones de llamadas.

Si el rendimiento le importa mucho, puede considerar escribir su propio complemento GCC haciendo aún más optimizaciones. Su complemento de compilación podría incluso implementar otras convenciones de llamada (por ejemplo, usando asmjit ).

Considere también mejorar TinyCC o Clang o NWCC para satisfacer sus necesidades.

Mi opinión es que en muchos casos no vale la pena dedicar meses de esfuerzo a mejorar el rendimiento en unos pocos nanosegundos. Pero su empleador/gerente/cliente podría no estar de acuerdo. Considere también compilar (o refactorizar) partes significativas de su software a silicio, por ejemplo, a través de VHDL , o usar hardware especializado, por ejemplo, GPGPU con OpenCL o CUDA .

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!