Fastmath est une bibliothèque de mathématiques Delphi qui est optimisée pour des performances rapides (parfois au prix de ne pas effectuer de vérification des erreurs ou de perdre un peu de précision). Il utilise le code d'assemblage optimisé à la main pour obtenir de bien meilleures performances que les fonctions équivalentes fournies par le Delphi RTL.
Cela rend Fastmath idéal pour les applications à forte intensité mathématique de haute performance telles que les applications et les jeux multimédias. Pour des performances encore meilleures, la bibliothèque offre une variété de fonctions "approximatives" (qui commencent toutes par un -prefix Fast ). Ceux-ci peuvent être très rapides, mais vous perdrez une précision (parfois étonnamment peu). Pour les jeux et l'animation, cette perte de précision est généralement parfaitement acceptable et l'emporte sur l'augmentation de la vitesse. Ne les utilisez pas pour les calculs scientifiques ...
Vous pouvez appeler DisableFloatingPointExceptions au démarrage d'application pour supprimer toutes les exceptions à virgule flottante. Au lieu de cela, il renverra des valeurs extrêmes (comme Nan ou Infinity) lorsqu'une opération ne peut pas être effectuée. Si vous utilisez FastMath dans plusieurs threads, vous devez appeler DisableFloatingPointExceptions dans le bloc Execute de ces threads.
La plupart des opérations peuvent être effectuées sur les deux valeurs singulières (scalaires) ainsi que sur les vecteurs (composés de valeurs 2, 3 ou 4). Le code d'assemblage optimisé SIMD est utilisé pour calculer plusieurs sorties en même temps. Par exemple, l'ajout de deux vecteurs à 4 valeurs ensemble est presque aussi rapide que d'ajouter deux valeurs uniques ensemble, entraînant une augmentation de vitesse de 4 fois. De nombreuses fonctions sont écrites de telle manière que la performance est encore meilleure.
Voici quelques exemples de facteurs d'accélération auxquels vous pouvez vous attendre sur différentes plates-formes:
| Rtl | Fastmath | x86-32 | x86-64 | ARM32 | ARM64 |
|---|---|---|---|---|---|
| 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.Normalise | TVECTOR4.Normalise | 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.inverse | Tmatrix4 | 9.8x | 9.2x | 8.0x | 9.8x |
| Sin (single) (x4) | FastSin (TVECTOR4) | 14.8x | 7.7x | 42.6x | 40.1x |
| Sincos (célibataire) (x4) | FastSincos (TVECTOR4) | 19.1x | 9.0x | 67,9x | 93.3x |
| Exp2 (simple) (x4) | FastExp2 (TVECTOR4) | 22.4x | 32,7x | 275.0x | 302.4x |
Comme vous pouvez le voir, certaines opérations très courantes (3D) comme la multiplication de la matrice et l'inversion peuvent être presque 10 fois plus rapides que leurs versions RTL correspondantes. De plus, Fastmath comprend un certain nombre de fonctions d'approximation Fast* qui sacrifient un peu de précision pour une énorme augmentation de vitesse. Par exemple, l'utilisation FastSinCos pour calculer 4 fonctions sinus et cosinus en parallèle peut être jusqu'à 90 fois plus rapide que d'appeler la fonction RTL SinCos 4 fois, tout en offrant une excellente précision pour les angles jusqu'à + / 4000 radians (ou +/- 230 000 degrés).
Sur les plates-formes de bureau 32 bits et 64 bits (Windows et OS X), ces performances sont obtenues en utilisant le jeu d'instructions SSE2. Cela signifie que l'ordinateur doit prendre en charge SSE2. Cependant, depuis que SSE2 a été introduit en 2001, la grande majorité des ordinateurs utilisés aujourd'hui le soutienont. Tous les ordinateurs de bureau 64 bits ont la prise en charge SSE2 par défaut. Cependant, vous pouvez toujours compiler cette bibliothèque avec la définition FM_NOSIMD pour désactiver l'optimisation SIMD et utiliser des versions PASCAL PLAIS. Cela peut également être utile pour comparer la vitesse des versions Pascal avec les versions optimisées SIMD.
Sur les plates-formes mobiles 32 bits (iOS et Android), l'ensemble d'instructions néon est utilisé pour l'optimisation SIMD. Cela signifie que votre appareil doit prendre en charge le néon. Mais comme Delphi l'exige déjà, cela ne présente aucune autre restriction.
Sur les plates-formes mobiles 64 bits (iOS), le jeu d'instructions SIMD ARM64 / AARCH64 est utilisé.
Il n'y a pas de prise en charge accélérée matérielle pour le simulateur iOS (il utilisera les versions Pascal pour tous les calculs).
FastMath Operations sur les valeurs à point flottante à une seule précision. L'arithmétique à virgule flottante à double précision est (actuellement) non soutenue.
La plupart des fonctions fonctionnent sur des valeurs uniques (de type Single ) et des vecteurs 2, 3 et 4 dimensions (de types TVector2 , TVector3 et TVector4 respectivement). Les vecteurs sont non seulement utilisés pour représenter des points ou des directions dans l'espace, mais peuvent également être considérés comme des tableaux de valeurs 2, 3 ou 4 qui peuvent être utilisées pour effectuer des calculs en parallèle. En plus des vecteurs à virgule flottante, il existe également des vecteurs qui opérateurs sur les valeurs entiers ( TIVector2 , TIVector3 et TIVector4 ).
Il existe également une prise en charge des matrices 2x2, 3x3 et 4x4 (appelées TMatrix2 , TMatrix3 et TMatrix4 ). Par défaut, les matrices sont stockées dans l'ordre des lignes de ligne, comme celles de l'unité System.Math.Vectors du RTL. Cependant, vous pouvez modifier cette mise en page avec la définition FM_COLUMN_MAJOR . Cela stockera à la place des matrices de colonnes-major, ce qui est utile pour les applications OpenGL (qui fonctionnent le mieux avec cette mise en page). De plus, cette définition coupera également la profondeur des matrices de caméra à -1..1 au lieu de la valeur par défaut 0..1. Encore une fois, cela est plus conforme à la valeur par défaut des applications OpenGL.
Pour représenter des rotations dans l'espace 3D, il existe également un TQuaternion , qui est similaire au type TQuaternion3D du RTL.
Le fonctionnement de la bibliothèque est quelque peu inspiré par les langues de shader (comme GLSL et HLSL). Dans ces langues, vous pouvez également traiter des valeurs et des vecteurs uniques de la même manière. Par exemple, vous pouvez utiliser la fonction Sin pour calculer une seule valeur sinusoïdale, mais vous pouvez également l'utiliser avec un type TVector4 pour calculer 4 valeurs sinusoïdales en un seul appel. Lorsqu'il est combiné avec les fonctions Fast* , cela peut entraîner une énorme augmentation des performances, comme indiqué précédemment.
Tous les types de vecteurs et de matrice prennent en charge les opérateurs surchargés qui vous permettent d'annuler, d'ajouter, de soustraire, de multiplier et de diviser les scalaires, les vecteurs et les matrices.
Il existe également des opérateurs surchargés qui comparent les vecteurs et les matrices pour l'égalité. Ces opérateurs vérifient les correspondances exactes (comme Delphi's = Operator). Ils ne permettent pas de très petites variations (comme les fonctions SameValue de Delphi).
Les opérateurs arithmétiques + , - , * et / travaillent généralement en termes de composants lorsqu'ils sont appliqués aux vecteurs. Par exemple, si A et B sont de type TVector4 , alors C := A * B définira C sur (AX * BX, AY * BY, AZ * BZ, AW * BW) . Il n'effectuera pas de produit DOT ou Cross (vous pouvez utiliser les fonctions Dot et Cross pour les calculer).
Pour les matrices, les opérateurs + et - fonctionnent également en termes de composants. Cependant, lors de la multiplication (ou de la division) des matrices avec des vecteurs ou d'autres matrices, la multiplication (ou division) algébrique linéaire habituelle est utilisée. Par exemple:
M := M1 * M2 effectue une multiplication de matrice algébrique linéaireV := M1 * V1 effectue une matrice * Vector de ligne Vector linéaire Multiplication algébriqueV := V1 * M1 effectue un vecteur de colonne * Matrice Multiplication algébrique linéaire Pour multiplier les matrices en termes de composants, vous pouvez utiliser la méthode CompMult .
Fastmath fournit ses propres types de vecteur et de matrice pour des performances supérieures. La plupart d'entre eux sont équivalents dans la fonctionnalité et le stockage de données aux types de Delphi RTL. Vous pouvez en tyran entre eux ou convertir implicitement du type FastMath en type RTL ou vice versa (par exemple MyVector2 := MyPointF ). Le tableau suivant montre le mappage:
| But | Fastmath | Delphi RTL |
|---|---|---|
| Point 2D / vecteur | TVECTOR2 | Tpointf |
| Point 3D / vecteur | TVECTOR3 | TPoint3d |
| 4d point / vecteur | TVECTOR4 | TVECTOR3D |
| 2x2 matrice | Tmatrix2 | N / A |
| Matrice 3x3 | Tmatrix3 | Tmatrice |
| Matrice 4x4 | Tmatrix4 | Tmatrix3d |
| quaternion | Tquaternion | Tquaternion3d |
La documentation peut être trouvée dans le fichier HTML d'aide à Fastmath.chm dans le répertoire Doc .
Alternativement, vous pouvez lire la documentation en ligne.
Le référentiel Fastmath contiennent les répertoires suivants:
Doc : Documentation au format htmlhelp. Contient également une feuille de calcul (Benchmarks.xlsx) avec les résultats des tests de performance sur mes appareils (un bureau Core i7 et iPad3).DocSource : contient des fichiers batch pour générer la documentation. Vous avez besoin de Pasdocex pour générer la documentation vous-même si vous le souhaitez.FastMath : contient l'unité principale Neslib.FastMath ainsi que divers fichiers incluent des fichiers avec des optimisations spécifiques au processeur et des bibliothèques statiques avec des versions optimisées ARM pour iOS et Android.Arm : code source et scripts spécifiques du bras.Arm32 : contient le code source de l'assembly pour les fonctions optimisées au néon ARM.Arm64 : contient le code source de l'assembly pour les fonctions optimisées ARM64.fastmath-android : contient un fichier batch et des fichiers d'assistance pour créer la bibliothèque statique pour Android à l'aide du NDK Android.fastmath-ios : contient un script shell macOS pour créer une bibliothèque statique universelle pour iOS.Tests : contient une application FireMenkey qui exécute des tests unitaires et des tests de performances. Fastmath est autorisé sous la licence BSD simplifiée. Certaines de ses fonctions sont basées sur le code d'autres personnes sous licence MIT, les nouvelles licences BSD et ZLIB. Ces licences sont aussi permissives que la licence BSD simplifiée utilisée pour l'ensemble du projet.
Voir Licence.txt pour plus de détails.