FastMath - Delphi的快速数学库

        FastMath 是 Delphi 数学库,旨在提高性能(有时会以牺牲错误检查或略微降低精度为代价)。它使用手工优化的汇编代码来实现比Delphi RTL提供的等效函数更好的性能。

        这使得FastMath非常适合用于高性能的数学密集型应用,例如多媒体应用和游戏。为了获得更好的性能,该库提供了一系列以“Fast-”前缀开头的“近似”函数。这些方法可以非常快速,但你可能会失去一些(有时是相当少的)精度。对于游戏和动画来说,这种精度上的损失通常是完全可以接受的,而且速度的提高可以抵消这种损失。不过不要用它们进行科学计算…

         您可能想要在应用程序启动时调用 DisableFloatingPointExceptions以抑制任何浮点异常。相反的是,当FastMath无法执行操作时,它将返回极值(如Nan或Infinity)。如果在多个线程中使用FastMath,则应该在这些线程的 Execute 块中调用DisableFloatingPointExceptions 。

高性能

        大多数操作既可以作用于标量(即单个值),也可以作用于向量(由2、3或4个值组成)。使用SIMD优化的汇编代码可以同时计算多个输出。例如,将两个4值向量相加几乎与将两个单个值相加一样快,从而导致速度提高4倍。许多函数都是以这样的方式编写的,性能甚至更好。

        下面是一些你可以在不同平台上预期的加速因素的例子:

RTLFastMathx86-32x86-64Arm32Arm64
TVector3D + TVector3DTVector4 + TVector41.2x1.6x2.8x2.5x
Single * TVector3DSingle * TVector42.2x2.1x5.6x3.7x
TVector3D.LengthTVector4.Length3.0x5.6x19.9x17.1x
TVector3D.NormalizeTVector4.Normalize4.1x5.1x7.4x11.7x
TVector3D * TMatrix3DTVector4 * TMatrix41.3x4.0x6.5x4.2x
TMatrix3D * TMatrix3DTMatrix4 * TMatrix42.2x7.2x5.4x8.0x
TMatrix3D.InverseTMatrix4.Inverse9.8x9.2x8.0x9.8x
Sin(Single) (x4)FastSin(TVector4)14.8x7.7x42.6x40.1x
SinCos(Single) (x4)FastSinCos(TVector4)19.1x9.0x67.9x93.3x
Exp2(Single) (x4)FastExp2(TVector4)22.4x32.7x275.0x302.4x

        如您所见,一些非常常见的(3D)操作,如矩阵乘法和求逆,其速度几乎是RTL版本的10倍。此外,FastMath还包含一些 Fast*近似函数,它们以略微降低精度为代价,实现了极大的速度提升。例如,使用 FastSinCos 并行计算4个正弦和余弦函数的速度可以比通过4次调用RTL SinCos 函数快90倍,同时在角度范围为+/4000 radians(或+/- 230,000度)时仍能提供出色的精度。

         在32位和64位桌面平台(Windows和OS X)上,该性能是通过使用SSE2指令集实现的。这意味着计算机必须支持SSE2。然而,自从SSE2在2001年推出以来,今天使用的绝大多数计算机都将支持它。所有64位桌面计算机默认支持SSE2。不过,您始终可以使用 FM_NOSIMD 定义指令编译此库来禁用SIMD优化,并使用纯Pascal版本的库。这还可以用来比较Pascal版本与SIMD优化版本的速度。

        在32位移动平台(iOS和Android)上,使用NEON指令集进行SIMD优化。这意味着您的设备需要支持NEON。但是由于Delphi本身已经需要这种方法,因此这不会带来额外的限制。

        在64位移动平台(iOS)上,使用Arm64/AArch64 SIMD指令集。

        iOS模拟器没有硬件加速支持(所有计算都将使用Pascal版本)。

架构和设计决策

        FastMath仅对单精度浮点值进行操作双精度浮点数运算目前尚未得到支持。

大多数函数对单个值(类型 Single)和2维、3维和4维向量(分别为 TVector2 、 TVector3 和 TVector4 类型)进行操作。向量不仅可以用来表示空间中的点或方向,还可以被视为具有2、3或4个值的数组,可以被用于并行执行计算。除了浮点向量,还有对整数值(TIVector2TIVector3 和 TIVector4)进行运算的向量。

        还支持2x2, 3x3和4x4矩阵(称为 TMatrix2TMatrix3 和 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 中的 = 运算符)它们允许存在非常小的差异(比如Delphi中的 SameValue 函数)。

        当应用于向量时,算术运算符+-* 和 / 通常按分量进行操作。例如,如果 A 和 B 是 TVector4类型,那么 C := A * B 将把 C 设置为 (A.X * B.X, A.Y * B.Y, A.Z * B.Z, A.W * B.W) 的值。它会执行点积或叉积(您可以使用 Dot 和 Cross 函数来计算这些值)。

        对于矩阵, + 和 - 操作符也会按分量进行操作。然而,当将矩阵与向量或其他矩阵相乘(或相除)时,通常使用线性代数中的乘法(或除法)。例如:

  • M := M1 * M2 执行线性代数矩阵乘法运算。
  • V := M1 * V1 执行矩阵*行向量的线性代数乘法
  • V := V1 * M1 执行列向量*矩阵线性代数乘法

        要对矩阵进行分量乘法运算,可以使用 CompMult 方法。

与Delphi运行时库(RTL)的互操作性

        FastMath 提供了自己的向量和矩阵类型,以实现更高的性能。它们中的大多数在功能和数据存储方面与Delphi RTL类型相当。你可以将它们之间进行类型转换,或者隐式地将 FastMath 类型转换为 RTL 类型或反之(例如:MyVector2 := MyPointF)。下表显示了映射关系:

目的FastMathDelphi RTL
2D point/vectorTVector2TPointF
3D point/vectorTVector3TPoint3D
4D point/vectorTVector4TVector3D
2x2 matrixTMatrix2N/A
3x3 matrixTMatrix3TMatrix
4x4 matrixTMatrix4TMatrix3D
quaternionTQuaternionTQuaternion3D

技术文档

        文档可以在 Doc 目录下的“FastMath.chm”HTML帮助文件中找到。

        或者,您可以在线阅读文档

目录组织

FastMath 存储库包含以下目录:

  • Doc: 以HtmlHelp格式编写的文档。还包含一个Excel表格(Benchmarks.xlsx),其中包含我在设备(Core i7台式机和iPad3)上进行的性能测试结果。
  • DocSource:包含用于生成文档的批处理文件。如果你想要的话,你需要使用 PasDocEx 来自行生成文档。
  • FastMath: 它包含了主要的 Neslib.FastMath 单元,以及各种处理器特定优化的包含文件,以及针对iOS和Android的Arm优化静态库。
    • Arm: 为特定的 Arm 架构编写源代码和脚本。
      • Arm32: 该库包含经过Arm Neon优化的函数的汇编源代码。
      • Arm64: 该文件包含针对Arm64优化的函数的汇编源代码。
      • fastmath-android: 该项目包含一个批处理文件和一些帮助文件,用于使用Android NDK构建Android静态库。
      • fastmath-ios: 该项目包含一个用于构建iOS通用静态库的macOS shell脚本。
  • Tests:: 该软件包包含一个使用FireMonkey编写的应用程序,用于运行单元测试和性能测试。

许可证

        FastMath 是按照简化的 BSD 许可证进行授权的。它的一些功能是基于其他人在MIT、New BSD和ZLib许可下的代码。这些许可证与整个项目使用的简化BSD许可证一样宽松。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值