2012-02-23 7 views
12

Después de leer todo el asunto, existe una abrumadora evidencia de numerosas fuentes de que el uso de conversiones en C o C++ estándar para convertir de coma flotante a números enteros en Intel es muy lento. Para cumplir con la especificación ANSI/ISO, las CPU Intel necesitan ejecutar una gran cantidad de instrucciones, incluidas las necesarias para cambiar el modo de redondeo del hardware de la FPU.¿Cómo me aseguro de que lrint está en línea en gcc?

Existen varios métodos alternativos descritos en diversos documentos, pero el más limpio y portátil parece ser el llamado lrint() agregado a los estándares C99 y C++ 0x. Muchos documentos dicen que un compilador debe expandir estas funciones cuando la optimización está habilitada, lo que lleva a un código que es más rápido que un molde convencional, o una llamada a función.

Incluso encontré referencias a las bolsas de seguimiento de funciones de gcc para agregar esta expansión en línea al optimizador de gcc, pero en mis propias pruebas de rendimiento no he podido hacerlo funcionar. Todos mis intentos muestran que el rendimiento de lrint es mucho más lento que un simple molde de estilo C o C++. Examinar la salida de ensamblaje del compilador y desensamblar los objetos compilados siempre muestra una llamada explícita a una función externa lrint() o lrintf().

Las versiones de gcc con las que he estado trabajando son 4.4.3 y 4.6.1, y he intentado varias combinaciones de banderas en objetivos de 32 bits y 64 bits x86, incluidas opciones para habilitar explícitamente SSE.

¿Cómo obtengo gcc en línea expandir lrint, y darme conversiones rápidas?

+1

¿Ha perfilado y confirmado que usar el lanzamiento obvio está tomando una cantidad significativa del tiempo de ejecución de tu programa? –

+2

La creación de perfiles muestra que puedo obtener una diferencia de velocidad de 2-4% usando una macro ensamblador escrita a mano levantada de un artículo. Esto vale la pena ya que el cálculo se realiza entre cuadros de una aplicación de renderizado 3D. –

+1

¿estableciste '-fno-math-errno'? también debería considerar usar '-ffast-math', que no siempre es una opción si confía en la semántica de fp específica ... – Christoph

Respuesta

10

La función lrint() puede provocar errores de dominio y rango. Una forma posible en que la libc se ocupa de tales errores es configurando errno (ver C99/C11 sección 7.12.1). La sobrecarga de la comprobación de errores puede ser bastante significativa y, en este caso particular, parece ser suficiente para que el optimizador decida no incluir la línea.

El indicador gcc -fno-math-errno (que es parte de -ffast-math) deshabilitará estas comprobaciones. Puede ser una buena idea mirar -ffast-math si no confía en el manejo conforme a los estándares de la semántica de coma flotante, en particular NaNs e infinitos ...

0

Has probado la bandera -finline-functions a gcc.

Puede GCC también directamente a tratar de integrar todas las funciones “bastante simple” en sus interlocutores con la opción -finline-functions.

ver http://gcc.gnu.org/onlinedocs/gcc/Inline.html

Aquí se puede decir gcc para hacer toda la función inline pero no todos estará en línea El compilador utiliza algunas heurísticas para determinar si la función es lo suficientemente pequeña como para estar en línea. Una cosa más es que una función recursiva tampoco va a estar en línea aquí.

+0

He intentado -finline-functions y no hizo ninguna diferencia en la salida del compilador. –

+0

si está utilizando lrint() de la biblioteca matemática en su código y compilando por gcc, entonces lrint() no se incluirá porque en su caso proviene de una biblioteca binaria vinculada. El código de lrint() no se va a insertar aquí –

+0

Este documento indica lo contrario: http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html "Las funciones de ISO C99 ..... lrintf, lrintl, lrint ...... se manejan como funciones incorporadas, excepto en el estricto modo ISO C90 (-ansi o -std = c90). " Más arriba del documento dice: "Muchas de estas funciones solo se optimizan en ciertos casos; si no se optimizan en un caso particular, se emitirá una llamada a la función de la biblioteca". pero no he podido encontrar un caso en el que estén optimizados. –

Cuestiones relacionadas