_ftol2_sse, ¿hay opciones más rápidas?

Tengo un código que llama mucho

int myNumber = (int)(floatNumber); 

que ocupa, en total, alrededor del 10% de mi tiempo de CPU (según el generador de perfiles). Si bien podría dejarlo así, me pregunto si hay opciones más rápidas, así que traté de buscar y me topé con

http://devmaster.net/forums/topic/7804-fast-int-float-conversion-routines/ http://stereopsis.com/FPU.html

Intenté implementar la función Real2Int () dada allí, pero me da resultados incorrectos y se ejecuta más lento. Ahora me pregunto, ¿hay implementaciones más rápidas para reducir los valores de doble / flotante a enteros, o es la versión SSE2 tan rápida como es posible? Las páginas que encontré se remontan un poco, por lo que podría estar desactualizada, y el nuevo STL es más rápido en esto.

La implementación actual hace:

 013B1030 call _ftol2_sse (13B19A0h) 013B19A0 cmp dword ptr [___sse2_available (13B3378h)],0 013B19A7 je _ftol2 (13B19D6h) 013B19A9 push ebp 013B19AA mov ebp,esp 013B19AC sub esp,8 013B19AF and esp,0FFFFFFF8h 013B19B2 fstp qword ptr [esp] 013B19B5 cvttsd2si eax,mmword ptr [esp] 013B19BA leave 013B19BB ret 

Preguntas relacionadas que encontré:

Rápida conversión de flotación a int y precisión de punto flotante en ARM (iPhone 3GS / 4)

¿Cuál es la forma más rápida de convertir float a int en x86?

Dado que ambos son viejos, o están basados ​​en ARM, me pregunto si hay formas actuales de hacer esto. Tenga en cuenta que dice que la mejor conversión es una que no ocurre, pero necesito tenerla, por lo que no será posible.

Va a ser difícil superar eso si está apuntando a un hardware x86 genérico. El tiempo de ejecución no sabe con seguridad si la máquina de destino tiene una unidad SSE. Si lo hiciera, podría hacer lo que hace el comstackdor x64 e cvttss2si un cvttss2si operación cvttss2si . Pero como el tiempo de ejecución tiene que verificar si una unidad SSE está disponible, se queda con la implementación actual. Eso es lo que hace la implementación de ftol2_sse . Y lo que es más, pasa el valor en un registro x87 y luego lo transfiere a un registro SSE si hay una unidad SSE disponible.

Podría decirle al comstackdor x86 que apunte a las máquinas que tienen unidades SSE. Entonces el comstackdor de hecho emitiría un simple código de operación cvttss2si línea. Eso va a ser lo más rápido que puedas conseguir. Pero si ejecuta el código en una máquina más antigua, entonces fallará. Tal vez podría suministrar dos versiones, una para máquinas con SSE y otra para máquinas sin SSE.

Eso no te va a ganar mucho. Solo se evitará toda la sobrecarga de ftol2_sse que suceda antes de llegar al cvttss2si operación cvttss2si que hace el trabajo.

Para cambiar la configuración del comstackdor desde el IDE, use Proyecto> Propiedades> Propiedades de configuración> C / C ++> Generación de código> Habilitar conjunto de instrucciones mejorado. En la línea de comandos está / arch: SSE o / arch: SSE2.

Para el double , no creo que pueda mejorar mucho los resultados, pero si tiene muchos float para convertir, el uso de una conversión empaquetada podría ayudar, lo siguiente es el código nasm :

 global _start section .data align 16 fv1: dd 1.1, 2.5, 2.51, 3.6 section .text _start: cvtps2dq xmm1, [fv1] ; Convert four 32-bit(single precision) floats to 32-bit(double word) integers and place the result in xmm1 

Debería haber un código intrínseco que le permita hacer lo mismo de una manera más fácil, pero no estoy tan familiarizado con el uso de bibliotecas intrínsecas. Aunque no está utilizando gcc en este artículo , la vectorización automática con gcc 4.7 es reveladora de lo difícil que puede ser conseguir que el comstackdor genere un buen código vectorizado.

Si necesita velocidad y una gran base de máquinas objective, es mejor que introduzca una versión SSE rápida de todos sus algoritmos, así como una genérica, y elija los algoritmos que se ejecutarán a un nivel mucho más alto.

Esto también significaría que también el ABI está optimizado para SSE; y que puede vectorizar el cálculo cuando esté disponible y que también la lógica de control está optimizada para la architecture.

por cierto incluso FLD; FIST FLD; FIST secuencia FLD; FIST no debería tomar más de ~ 7 ciclos de reloj en Pentium.