FastMath是一个Delphi数学库,已针对快速性能进行了优化(有时以不执行错误检查或失去一些精度为代价)。它使用手动优化的装配代码来实现比Delphi RTL提供的等效功能更好的性能。
这使得非常适合高性能数学密集型应用程序,例如多媒体应用程序和游戏。为了获得更好的性能,该库提供了各种“近似”功能(所有这些功能都以Fast冠军开头)。这些可能非常快,但是您会失去一些(有时令人惊讶的)精度。对于游戏和动画,这种准确性的损失通常是完全可以接受的,并且速度的提高超过了。不过不要将它们用于科学计算...
您可能需要在应用程序启动时调用DisableFloatingPointExceptions ,以抑制任何浮点异常。取而代之的是,当无法执行操作时,它将返回极端值(例如NAN或Infinity)。如果您在多个线程中使用快速固定,则应在这些线程的Execute块中调用DisableFloatingPointExceptions 。
大多数操作都可以在单数值(标量)和向量(由2、3或4个值组成)上执行。 SIMD优化的装配代码用于同时计算多个输出。例如,将两个4值向量添加在一起几乎与将两个单个值添加在一起一样快,从而增加了4倍速度。许多功能的编写方式使性能更好。
以下是您可以在不同平台上期望的加速因素的一些示例:
| RTL | Fastmath | x86-32 | X86-64 | ARM32 | ARM64 |
|---|---|---|---|---|---|
| TVECTOR3D + TVECTOR3D | TVECTOR4 + TVECTOR4 | 1.2倍 | 1.6倍 | 2.8倍 | 2.5倍 |
| 单 * TVECTOR3D | 单 * TVECTOR4 | 2.2x | 2.1倍 | 5.6倍 | 3.7倍 |
| TVECTOR3D.LENGTH | tvector4.4length | 3.0x | 5.6倍 | 19.9倍 | 17.1x |
| TVECTOR3D.Normorize | TVECTOR4.SROMALIZE | 4.1倍 | 5.1倍 | 7.4倍 | 11.7倍 |
| TVECTOR3D * TMATRIX3D | TVector4 * tmatrix4 | 1.3倍 | 4.0x | 6.5倍 | 4.2x |
| tmatrix3d * tmatrix3d | tmatrix4 * tmatrix4 | 2.2x | 7.2倍 | 5.4倍 | 8.0x |
| tmatrix3d.inverse | tmatrix4.inverse | 9.8倍 | 9.2x | 8.0x | 9.8倍 |
| 罪(单)(x4) | Fastsin(TVector4) | 14.8倍 | 7.7倍 | 42.6倍 | 40.1x |
| Sincos(单)(x4) | FastSincos(TVector4) | 19.1x | 9.0x | 67.9倍 | 93.3x |
| exp2(单)(x4) | fastexp2(tvector4) | 22.4倍 | 32.7倍 | 275.0x | 302.4x |
如您所见,一些非常常见的(3D)操作(例如矩阵乘法和反转)的速度几乎比相应的RTL版本快10倍。此外,FastMath还具有许多Fast*近似函数,这些函数牺牲了一些精确度以增加速度。例如,使用FastSinCos与调用RTL SINCOS函数的速度高达90倍的速度可比调用RTL SinCos函数的速度高90倍,同时仍然为角度提供出色的精度至 +/4000弧度(OR +/- 230,000度)。
在32位和64位桌面平台(Windows和OS X)上,使用SSE2指令集实现此性能。这意味着计算机必须支持SSE2。但是,由于SSE2于2001年推出,因此当今使用的绝大多数计算机都将支持它。默认情况下,所有64位台式计算机均具有SSE2支持。但是,您始终可以使用FM_NOSIMD定义以禁用SIMD优化并使用普通Pascal版本来编译此库。这对于将PASCAL版本的速度与SIMD优化版本进行比较也很有用。
在32位移动平台(iOS和Android)上,霓虹灯指令集用于SIMD优化。这意味着您的设备需要支持霓虹灯。但是,由于德尔菲已经需要这一点,所以这没有进一步的限制。
在64位移动平台(iOS)上,使用ARM64/AARCH64 SIMD指令集。
没有对iOS模拟器的硬件加速支持(它将使用Pascal版本进行所有计算)。
仅在单精度浮点数值上操作。双精度浮点算术是(当前)不支持的。
大多数函数在单个值(类型Single )和2-,3-和4维向量(分别为TVector2 , TVector3和TVector4 )上运行。向量不仅用于表示空间中的点或方向,而且还可以视为2、3或4个值的阵列,可通过并行执行计算。除了浮点矢量外,还有对整数值的载体( TIVector2 , TIVector3和TIVector4 )。
还支持2x2、3x3和4x4矩阵(称为TMatrix2 , TMatrix3和TMatrix4 )。默认情况下,像RTL的System.Math.Vectors单元中的矩阵一样,按行订单存储。但是,您可以使用FM_COLUMN_MAJOR定义更改此布局。这将以列列订单存储矩阵,这对OpenGL应用程序很有用(与此布局最有用)。此外,此定义还将剪辑相机矩阵的深度为-1..1,而不是默认的0..1。同样,这与OpenGL应用程序的默认值一致。
为了表示3D空间中的旋转,还有一个TQuaternion ,类似于RTL的TQuaternion3D类型。
图书馆的操作在某种程度上受到着色器语言(例如GLSL和HLSL)的启发。在这些语言中,您还可以类似地对待单个值和向量。例如,您可以使用Sin函数来计算单个正弦值,但是您也可以将其与TVector4类型一起使用,以在一个呼叫中计算4个正弦值。当与近似Fast*函数结合使用时,这可能会导致巨大的性能提升,如前所述。
所有向量和矩阵类型都支持超载的运算符,使您可以否定,添加,减,乘和分割标量,向量和矩阵。
还有一些超载的操作员比较向量和矩阵以保持平等。这些操作员检查确切的匹配(例如Delphi's = Operator)。它们不允许很小的变化(例如Delphi的SameValue功能)。
当应用于向量时,算术运算符+ , - *和/通常会在组件上工作。例如,如果A和B是类型TVector4 ,则C := A * B将将C设置为(AX * BX, AY * BY, AZ * BZ, AW * BW) 。它不会执行点或跨产品(您可以使用Dot和Cross功能来计算这些点)。
对于矩阵, +和-操作员还可以在组件上操作。但是,当用向量或其他矩阵繁殖(或分隔)矩阵时,则使用通常的线性代数乘法(或除法)。例如:
M := M1 * M2执行线性代数矩阵乘法V := M1 * V1执行矩阵 *行矢量线性代数乘法V := V1 * M1执行列矢量 *矩阵线性代数乘法为了使矩阵组成部分,您可以使用CompMult方法。
FastMath提供了自己的向量和矩阵类型,可提供出色的性能。它们中的大多数在功能和数据存储方面等效于Delphi RTL类型。您可以在它们之间类型或隐式转换为RTL类型,反之亦然(例如MyVector2 := MyPointF )。下表显示了映射:
| 目的 | Fastmath | Delphi RTL |
|---|---|---|
| 2D点/向量 | TVector2 | tpointf |
| 3D点/向量 | TVECTOR3 | tpoint3d |
| 4D点/向量 | TVECTOR4 | TVECTOR3D |
| 2x2矩阵 | tmatrix2 | N/A。 |
| 3x3矩阵 | tmatrix3 | tmatrix |
| 4x4矩阵 | tmatrix4 | tmatrix3d |
| 季节 | tquaternion | tquaternion3d |
文档可以在Doc目录中的HTML帮助文件fastmath.chm中找到。
另外,您可以在线阅读文档。
FastMath存储库包含以下目录:
Doc :htmlhelp格式的文档。还包含一个电子表格(benchmarks.xlsx),并在设备上进行性能测试结果(Core i7台式机和iPad3)。DocSource :包含用于生成文档的批处理文件。如果您愿意,您需要Pasdocex自己生成文档。FastMath :包含Neslib.FastMath主要单元,以及各种包含具有特定于处理器的优化的文件,以及具有iOS和Android ARM优化版本的静态库。Arm :特定的源代码和脚本。Arm32 :包含用于ARM霓虹灯优化功能的组装源代码。Arm64 :包含用于ARM64优化功能的装配源代码。fastmath-android :包含一个批处理文件和辅助文件,以使用Android NDK构建Android的静态库。fastmath-ios :包含一个MacOS Shell脚本,用于构建iOS通用静态库。Tests :包含一个运行单元测试和性能测试的Firemonkey应用程序。 Fastmath已根据简化的BSD许可获得许可。它的某些功能是基于在麻省理工学院,新BSD和ZLIB许可下获得许可的其他人的代码。这些许可与整个项目使用的简化BSD许可一样允许。
有关详细信息,请参见License.txt。