FastMath es una biblioteca de matemáticas de Delphi que está optimizada para un rendimiento rápido (a veces a costa de no realizar una verificación de errores o perder una pequeña precisión). Utiliza un código de ensamblaje optimizado para lograr un rendimiento mucho mejor que las funciones equivalentes proporcionadas por Delphi RTL.
Esto hace que FastMath sea ideal para aplicaciones intensivas en matemáticas de alto rendimiento, como aplicaciones y juegos multimedia. Para un rendimiento aún mejor, la biblioteca proporciona una variedad de funciones "aproximadas" (que comienzan con un resefs Fast ). Estos pueden ser muy rápidos, pero perderá algo (a veces sorprendentemente poca) precisión. Para los juegos y la animación, esta pérdida de precisión suele ser perfectamente aceptable y verificada por el aumento de la velocidad. Sin embargo, no los uses para los cálculos científicos ...
Es posible que desee llamar a DisableFloatingPointExceptions al inicio de la aplicación para suprimir cualquier excepción de punto flotante. En cambio, devolverá valores extremos (como Nan o Infinity) cuando no se puede realizar una operación. Si usa FastMath en múltiples hilos, debe llamar a DisableFloatingPointExceptions en el bloque Execute de esos hilos.
La mayoría de las operaciones se pueden realizar tanto en valores singulares (escalares) como en vectores (que consisten en 2, 3 o 4 valores). El código de ensamblaje optimizado SIMD se usa para calcular múltiples salidas al mismo tiempo. Por ejemplo, agregar dos vectores de 4 valores juntos es casi tan rápido como agregar dos valores individuales juntos, lo que resulta en un aumento de velocidad de 4 veces. Muchas funciones están escritas de tal manera que el rendimiento es aún mejor.
Aquí hay algunos ejemplos de factores de velocidad que puede esperar en diferentes plataformas:
| RTL | Fastmath | X86-32 | x86-64 | Brazo | Brazo |
|---|---|---|---|---|---|
| Tvector3d + tvector3d | Tvector4 + tvector4 | 1.2x | 1.6x | 2.8x | 2.5x |
| Single * tvector3d | Single * tvector4 | 2.2x | 2.1x | 5.6x | 3.7x |
| Tvector3d.length | Tvector4.length | 3.0x | 5.6x | 19.9x | 17.1x |
| Tvector3d.normalize | Tvector4.normalizar | 4.1x | 5.1x | 7.4x | 11.7x |
| Tvector3d * tmatrix3d | Tvector4 * tmatrix4 | 1.3x | 4.0x | 6.5x | 4.2x |
| Tmatrix3d * tmatrix3d | Tmatrix4 * tmatrix4 | 2.2x | 7.2x | 5.4x | 8.0x |
| Tmatrix3d.inverso | Tmatrix4.inverso | 9.8x | 9.2x | 8.0x | 9.8x |
| Sin (single) (x4) | Fastsin (Tvector4) | 14.8x | 7.7x | 42.6x | 40.1x |
| Sincos (single) (x4) | Fastsincos (Tvector4) | 19.1x | 9.0x | 67.9x | 93.3x |
| Exp2 (single) (x4) | FastEXP2 (TVECTOR4) | 22.4x | 32.7x | 275.0x | 302.4x |
Como puede ver, algunas operaciones muy comunes (3D) como la multiplicación de matriz e inversión pueden ser casi 10 veces más rápidas que sus versiones RTL correspondientes. Además, FastMath incluye una serie de funciones de aproximación Fast* que sacrifican un poco de precisión por un aumento de velocidad enorme. Por ejemplo, el uso de FastSinCos para calcular 4 funciones seno y coseno en paralelo puede ser hasta 90 veces más rápido que llamar a la función RTL SinCos 4 veces, al tiempo que proporciona una excelente precisión para ángulos de hasta +/4000 radianos (o +/- 230,000 grados).
En plataformas de escritorio de 32 bits y 64 bits (Windows y OS X), este rendimiento se logra utilizando el conjunto de instrucciones SSE2. Esto significa que la computadora debe admitir SSE2. Sin embargo, dado que SSE2 se introdujo en 2001, la gran mayoría de las computadoras en uso hoy en día lo respaldarán. Todas las computadoras de escritorio de 64 bits tienen soporte SSE2 de forma predeterminada. Sin embargo, siempre puede compilar esta biblioteca con el FM_NOSIMD Definir para deshabilitar la optimización de SIMD y usar versiones PASCAL simples. Esto también puede ser útil para comparar la velocidad de las versiones Pascal con las versiones optimizadas SIMD.
En las plataformas móviles de 32 bits (iOS y Android), el conjunto de instrucciones de neón se utiliza para la optimización SIMD. Esto significa que su dispositivo necesita admitir neón. Pero dado que Delphi ya requiere esto, esto no plantea más restricciones.
En las plataformas móviles de 64 bits (iOS), se utiliza el conjunto de instrucciones ARM64/AARCH64 SIMD.
No hay soporte acelerado de hardware para el simulador iOS (usará versiones Pascal para todos los cálculos).
Operaciones de FastMath solo en valores de punto flotante de precisión única. La aritmética de punto flotante de doble precisión es (actualmente) sin apoyo.
La mayoría de las funciones funcionan con valores individuales (de tipo Single ) y vectores 2, 3 y 4 dimensionales (de Tipos TYS TVector2 , TVector3 y TVector4 respectivamente). Los vectores no solo se usan para representar puntos o direcciones en el espacio, sino que también pueden considerarse como matrices de 2, 3 o 4 valores que pueden usarse para realizar cálculos en paralelo. Además de los vectores de punto flotante, también hay vectores que operan en valores enteros ( TIVector2 , TIVector3 y TIVector4 ).
También hay soporte para matrices 2x2, 3x3 y 4x4 (llamadas TMatrix2 , TMatrix3 y TMatrix4 ). Por defecto, las matrices se almacenan en el orden de mayúsculas, como las de la unidad System.Math.Vectors de RTL. Sin embargo, puede cambiar este diseño con FM_COLUMN_MAJOR Definir. Esto almacenará matrices en el orden de columna mayor, lo que es útil para aplicaciones OpenGL (que funcionan mejor con este diseño). Además, esto Define también recortará la profundidad de las matrices de cámara a -1..1 en lugar del valor predeterminado 0..1. Nuevamente, esto está más en línea con el valor predeterminado para las aplicaciones OpenGL.
Para representar rotaciones en el espacio 3D, también hay un TQuaternion , que es similar al tipo TQuaternion3D de RTL.
La operación de la biblioteca está algo inspirada en los idiomas de los sombreadores (como GLSL y HLSL). En esos idiomas también puede tratar valores y vectores individuales de manera similar. Por ejemplo, puede usar la función Sin para calcular un solo valor sinusoidal, pero también puede usarlo con un tipo de TVector4 para calcular 4 valores seno en una llamada. Cuando se combina con las funciones Fast* , esto puede resultar en un enorme impulso de rendimiento, como se mostró anteriormente.
Todos los tipos de vectores y matrices admiten operadores sobrecargados que le permiten negar, agregar, restar, multiplicar y dividir escalares, vectores y matrices.
También hay operadores sobrecargados que comparan vectores y matrices de igualdad. Estos operadores verifican las coincidencias exactas (como Delphi's = Operator). No permiten variaciones muy pequeñas (como las funciones SameValue de Delphi).
Los operadores aritméticos + , - , * y / generalmente trabajan en cuanto a componentes cuando se aplican a los vectores. Por ejemplo, si A y B son de tipo TVector4 , entonces C := A * B establecerá C (AX * BX, AY * BY, AZ * BZ, AW * BW) . No realizará un punto o producto cruzado (puede usar las funciones Dot y Cross para calcularlas).
Para las matrices, los operadores + y - también operan componentes. Sin embargo, al multiplicar (o dividir) matrices con vectores u otras matrices, se usa la multiplicación algebraica lineal habitual (o división). Por ejemplo:
M := M1 * M2 realiza una multiplicación de matriz algebraica linealV := M1 * V1 realiza una matriz * Multiplicación algebraica lineal de vector de filaV := V1 * M1 realiza un vector de columna * multiplicación algebraica lineal matriz Para multiplicar las matrices en cuanto al componente, puede usar el método CompMult .
FastMath proporciona sus propios tipos de vectores y matrices para un rendimiento superior. La mayoría de ellos son equivalentes en funcionalidad y almacenamiento de datos a los tipos Delphi RTL. Puede escribir entre ellos o convertir implícitamente del tipo FastMath al tipo RTL o viceversa (por ejemplo, MyVector2 := MyPointF ). La siguiente tabla muestra el mapeo:
| Objetivo | Fastmath | Delphi RTL |
|---|---|---|
| 2D Point/Vector | TVECTOR2 | Tpointf |
| Punto 3D/vector | Tvector3 | Tpoint3d |
| 4D Point/Vector | Tvector4 | Tvector3d |
| Matriz 2x2 | Tmatrix2 | N / A |
| 3x3 matriz | Tmatrix3 | Tmatriz |
| Matriz 4x4 | Tmatrix4 | Tmatrix3d |
| cuaternio | Tquaternion | Tquaternion3d |
La documentación se puede encontrar en el archivo de ayuda HTML FastMath.Chm en el directorio Doc .
Alternativamente, puede leer la documentación en línea.
El repositorio de FastMath contiene los siguientes directorios:
Doc : Documentación en formato HTMLHelp. También contiene una hoja de cálculo (Benchmarks.xlsx) con resultados de pruebas de rendimiento en mis dispositivos (un escritorio Core i7 y iPad3).DocSource : contiene archivos por lotes para generar la documentación. Necesita Pasdocex para generar la documentación usted mismo si lo desea.FastMath : contiene la unidad Neslib.FastMath principal, así como varios archivos de incluido con optimizaciones específicas del procesador y bibliotecas estáticas con versiones optimizadas de ARM para iOS y Android.Arm : Código fuente específico del brazo y scripts.Arm32 : contiene el código fuente de ensamblaje para funciones optimizadas de neón ARM.Arm64 : contiene el código fuente de ensamblaje para funciones optimizadas ARM64.fastmath-android : contiene un archivo por lotes y archivos auxiliares para construir la biblioteca estática para Android usando el NDK de Android.fastmath-ios : contiene un script de shell de macOS para construir una biblioteca estática universal para iOS.Tests : contiene una aplicación Firemonkey que ejecuta pruebas unitarias y pruebas de rendimiento. FastMath tiene licencia bajo la licencia BSD simplificada. Algunas de sus funciones se basan en el código de otras personas con licencia bajo el MIT, nuevas licencias BSD y ZLIB. Esas licencias son tan permisivas como la licencia BSD simplificada utilizada para todo el proyecto.
Consulte License.txt para más detalles.