tipos - ¿Los dobles son más rápidos que los flotantes en C#?
tipo de dato float en c (10)
Esto indica que los flotantes son ligeramente más rápidos que los dobles: http://www.herongyang.com/cs_b/performance.html
En general, cada vez que hace una comparación del rendimiento, debe tener en cuenta los casos especiales, como si usar un tipo requiriera conversiones adicionales o masajes de datos. Esos se suman y pueden desmentir los puntos de referencia genéricos como este.
Estoy escribiendo una aplicación que lee grandes conjuntos de flotadores y realiza algunas operaciones simples con ellos. Estoy usando carrozas, porque pensé que sería más rápido que el doble, pero después de investigar un poco descubrí que hay cierta confusión sobre este tema. ¿Alguien puede explicar esto?
Si las operaciones de carga y almacenamiento son el cuello de botella, los flotadores serán más rápidos porque son más pequeños. Si realiza una gran cantidad de cálculos entre cargas y tiendas, debería ser aproximadamente igual.
Alguien más mencionó evitar conversiones entre float y double, y cálculos que usan operandos de ambos tipos. Es un buen consejo, y si usa cualquier función de la biblioteca matemática que devuelva dobles (por ejemplo), entonces mantener todo como dobles será más rápido.
Con la aritmética de 387 FPU, float solo es más rápido que el doble para ciertas operaciones iterativas largas como pow, log, etc. (y solo si el compilador establece apropiadamente la palabra de control FPU).
Sin embargo, con la aritmética SSE empaquetada, hace una gran diferencia.
Hice un perfil de una pregunta similar hace unas semanas. La conclusión es que para el hardware x86, no hay una diferencia significativa en el rendimiento de los flotantes versus los dobles, a menos que te limites a la memoria, o comiences a tener problemas con el 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 coma flotante en registros de 80 bits de ancho, por lo que la velocidad real del cálculo no debe variar entre flotantes y dobles.
Estoy escribiendo un rastreador 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 genial :)
Eso es con un Core i7 920
Acabo de leer "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 tipos incorporados
El tiempo de ejecución optimiza el rendimiento de los tipos enteros de 32 bits (Int32 y UInt32), por lo tanto, use esos tipos para los contadores y otras variables integrales a las que se accede con frecuencia. Para operaciones de coma 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 esperaría que el libro oficial para el examen .NET tenga algo de peso. Por supuesto, no es una garantía. Solo pensé en agregarlo a esta discusión.
La respuesta corta es: "use la precisión que se requiera para obtener resultados aceptables".
Su única garantía es que las operaciones realizadas en datos de coma flotante se realizan en al menos el miembro de mayor precisión de la expresión. Así que multiplicar dos flotadores se hace con al menos la precisión de flotación , y multiplicar un flotador y un doble se haría con al menos precisión doble. La norma establece que "las operaciones de [coma flotante] se pueden realizar con mayor precisión que el tipo de resultado de la operación".
Dado que el JIT para .NET intenta dejar sus operaciones de punto flotante con la precisión solicitada, podemos echarle un vistazo a la documentación de Intel para acelerar nuestras operaciones. En la plataforma Intel, las operaciones de coma flotante se pueden realizar con una precisión intermedia de 80 bits y se pueden convertir a la precisión solicitada.
De la guía de Intel a C ++ Operaciones de punto flotante 1 (lo siento solo tienen árbol muerto), mencionan:
- Utilice un solo tipo de precisión (por ejemplo, flotante) 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. ...
- Evite expresiones aritméticas de tipos de datos mixtos
Ese último punto es importante, ya que puede ralentizarse con conversiones innecesarias hacia / desde flotación y doble , lo que da como resultado el código JIT que solicita que el x87 abandone su formato intermedio de 80 bits entre operaciones.
1. Sí, dice C ++, pero el estándar C # más el conocimiento del CLR nos permite saber que la información para C ++ debería ser aplicable en esta instancia.
Los flotantes deben ser más rápidos en un sistema de 32 bits, pero el perfil del código para asegurarse de que está optimizando lo correcto.
Siempre he pensado que los procesadores fueron optimizados o lo mismo independientemente de flotación o doble. Buscando optimizaciones en mis cálculos intensivos (muchos obtiene de una matriz, comparaciones de dos valores) descubrí que los flotantes se ejecutan aproximadamente un 13% más rápido.
Esto me sorprendió, pero creo que es debido a la naturaleza de mi problema. No hago lanzamientos entre float y double en el núcleo de las operaciones, y mis cálculos se basan principalmente en sumar, multiplicar y restar.
Esto está en mi i7 920, ejecutando un sistema operativo de 64 bits.
Está usted equivocado. 32 bits es mucho más eficiente que 16 bits, en los procesadores modernos ... Tal vez no en cuanto a la memoria, pero en la efectividad de 32 bits es el camino a seguir.
Deberías actualizar a tu profesor a algo más "actualizado". ;)
De todos modos, para responder la pregunta; flotante y doble 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í 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