Pregunta

Estoy escribiendo una aplicación que lee grandes arreglos de flotadores y realiza algunas operaciones simples con ellos. Estoy usando flotadores, porque pensé que sería más rápido que los dobles, pero después de hacer algunas investigaciones descubrí que existe cierta confusión sobre este tema. ¿Alguien puede dar más detalles sobre esto?

¿Fue útil?

Solución

La respuesta corta es, " use la precisión que sea necesaria para obtener resultados aceptables. "

Su única garantía es que las operaciones realizadas en datos de punto flotante se realizan al menos en el miembro de mayor precisión de la expresión. Por lo tanto, multiplicar dos flotadores se realiza con al menos la precisión de flotadores , y multiplicar un flotador y un doble Se haría con al menos doble precisión. El estándar establece que las operaciones " [punto flotante] se pueden realizar con mayor precisión que el tipo de resultado de la operación. & Quot;

Dado que el JIT para .NET intenta dejar sus operaciones de punto flotante en la precisión solicitada, podemos ver la documentación de Intel para acelerar nuestras operaciones. En la plataforma Intel, sus operaciones de punto flotante pueden realizarse con una precisión intermedia de 80 bits y convertirse a la precisión solicitada.

De la guía de Intel para operaciones de punto flotante en C ++ 1 (perdón solo tiene un árbol muerto), mencionan:

  
      
  • Use un tipo de precisión simple (por ejemplo, flotador) a menos que se requiera la precisión adicional obtenida a través del doble o el doble largo. Los tipos de mayor precisión aumentan el tamaño de la memoria y los requisitos de ancho de banda.   ...
  •   
  • Evitar expresiones aritméticas de tipos de datos mixtos
  •   

El último punto es importante como puede ralentizarse caiga con conversiones innecesarias a / desde flotante y doble , lo que da como resultado un código JIT que solicita al x87 que se aleje de su formato intermedio de 80 bits entre operaciones.

1. Sí, dice C ++, pero el conocimiento del estándar C # más el CLR nos permite saber que la información para C ++ debe ser aplicable en este caso.

Otros consejos

Acabo de leer el " Microsoft .NET Framework-Application Development Foundation 2nd " para el examen MCTS 70-536 y hay una nota en la página 4 (capítulo 1):

  

NOTA Optimización del rendimiento con los tipos integrados
  El tiempo de ejecución optimiza el rendimiento de los tipos de enteros de 32 bits (Int32 y UInt32), así que use esos tipos para contadores y otras variables integrales de acceso frecuente. Para las operaciones de punto flotante, Double es el tipo más eficiente porque esas operaciones están optimizadas por hardware.

Está escrito por Tony Northrup. No sé si él es una autoridad o no, pero espero que el libro oficial para el examen .NET tenga algún peso. Por supuesto, no es una garantía. Solo pensé que lo añadiría a esta discusión.

Hace unas semanas hice una pregunta similar. La conclusión es que para el hardware x86, no hay una diferencia significativa en el rendimiento de los flotantes en lugar de los dobles a menos que se convierta en un enlace de memoria, o comience a tener problemas de caché. En ese caso, los flotadores generalmente tendrán la ventaja porque son más pequeños.

Las CPU Intel actuales realizan todas las operaciones de punto flotante en registros de 80 bits de ancho, por lo que la velocidad real del cálculo no debe variar entre flotantes y dobles.

Si carga & amp; las operaciones de la tienda son el cuello de botella, luego las flotaciones serán más rápidas, porque son más pequeñas. Si está haciendo una cantidad significativa de cálculos entre cargas y almacenes, debería ser aproximadamente igual.

Alguien más mencionó evitar las conversiones entre float y amp; Doble, y cálculos que utilizan operandos de ambos tipos. Eso es un buen consejo, y si utiliza alguna función de biblioteca matemática que devuelva dobles (por ejemplo), mantener todo como dobles será más rápido.

Estoy escribiendo un trazador de rayos, y reemplazar los flotadores con dobles para mi clase de Color me da un 5% de aceleración. ¡Reemplazar los flotadores de vectores con dobles es otro 5% más rápido! Muy bien :)

Eso es con un Core i7 920

Con 387 FPU aritmética, float es solo más rápido que el doble para ciertas operaciones iterativas largas como pow, log, etc. (y solo si el compilador establece la palabra de control de FPU de manera apropiada).

Sin embargo, con la aritmética SSE empaquetada, hace una gran diferencia.

Matthijs,

Estás equivocado. Los 32 bits son mucho más eficientes que los de 16 bits. En los procesadores modernos ... Tal vez no sea en lo que respecta a la memoria, pero en la efectividad es el camino a seguir.

Realmente deberías actualizar a tu profesor a algo más " actualizado " ;. ;)

De todos modos, para responder a la pregunta; float and double tiene exactamente el mismo rendimiento, al menos en mi Intel i7 870 (como en teoría).

Aquí están mis medidas:

(hice un "algoritmo" que repetí por 10,000,000 de veces, y luego lo repetí por 300 veces, y de eso hice un promedio.)

double
-----------------------------
1 core  = 990 ms
4 cores = 340 ms
6 cores = 282 ms
8 cores = 250 ms

float
-----------------------------
1 core  = 992 ms
4 cores = 340 ms
6 cores = 282 ms
8 cores = 250 ms

Esto indica que los flotadores son ligeramente más rápidos que los dobles: http://www.herongyang.com /cs_b/performance.html

En general, cada vez que realice una comparación sobre el rendimiento, debe tener en cuenta los casos especiales, ¿por ejemplo, el uso de un tipo requiere conversiones adicionales o un masaje de datos? Esos se suman y pueden rechazar puntos de referencia genéricos como este.

Los flotadores deben ser más rápidos en un sistema de 32 bits, pero perfila el código para asegurarte de que estás optimizando lo correcto.

Siempre he pensado que los procesadores estaban optimizados o eran iguales independientemente de la flotación o el doble. Buscando optimizaciones en mis cálculos intensivos (muchos resultados de una matriz, comparaciones de dos valores) descubrí que las flotaciones se ejecutan aproximadamente un 13% más rápido.

Esto me sorprendió, pero supongo que se debe a la naturaleza de mi problema. No hago lanzamientos entre flotación y doble en el núcleo de las operaciones, y mis cálculos son principalmente sumar, multiplicar y restar.

Esto está en mi i7 920, ejecutando un sistema operativo de 64 bits.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top