Fastmathは、速いパフォーマンスのために最適化されたDelphi Math Libraryです(エラーチェックを実行したり、少しの精度を失ったりしない場合がある場合もあります)。 Delphi RTLが提供する同等の関数よりもはるかに優れたパフォーマンスを実現するために、手最適化されたアセンブリコードを使用します。
これにより、Fastmathは、マルチメディアアプリケーションやゲームなどの高性能数学集約型アプリケーションに最適です。パフォーマンスをさらに向上させるために、ライブラリはさまざまな「おおよその」関数を提供します(すべてFast -Prefixで始まります)。これらは非常に高速になる可能性がありますが、(驚くほど少ない)精度を失う可能性があります。ゲームとアニメーションの場合、この精度の損失は通常、完全に受け入れられ、速度の上昇により上回ります。科学的な計算にそれらを使用しないでください...
アプリケーションの起動時にDisableFloatingPointExceptionsを呼び出して、浮動小数点の例外を抑制することをお勧めします。代わりに、操作が実行できないときに(NANやInfinityなど)極値(NANやInfinityなど)を返します。複数のスレッドでFastmathを使用する場合は、それらのスレッドのExecuteブロックでDisableFloatingPointExceptions呼び出す必要があります。
ほとんどの操作は、単数値(スカラー)とベクトル(2、3、または4の値で構成される)の両方で実行できます。 SIMD最適化されたアセンブリコードは、複数の出力を同時に計算するために使用されます。たとえば、2つの4価値ベクトルを一緒に追加することは、2つの単一値を一緒に追加するのとほぼ同じ速さで、4倍の速度が上昇します。多くの機能は、パフォーマンスがさらに優れているように書かれています。
さまざまなプラットフォームで期待できるスピードアップ要因の例をいくつか紹介します。
| RTL | Fastmath | x86-32 | x86-64 | ARM32 | ARM64 |
|---|---|---|---|---|---|
| tvector3d + tvector3d | tvector4 + tvector4 | 1.2x | 1.6x | 2.8x | 2.5x |
| 単一 * tvector3d | 単一 * tvector4 | 2.2x | 2.1x | 5.6x | 3.7x |
| tvector3d.length | tvector4.length | 3.0x | 5.6x | 19.9x | 17.1x |
| tvector3d.normalize | tvector4.normalize | 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.inverse | 9.8x | 9.2x | 8.0x | 9.8x |
| sin(single)(x4) | fastsin(tvector4) | 14.8x | 7.7x | 42.6x | 40.1x |
| シンコス(シングル)(x4) | fastsincos(tvector4) | 19.1x | 9.0x | 67.9x | 93.3x |
| exp2(single)(x4) | FASTEXP2(tvector4) | 22.4x | 32.7x | 275.0x | 302.4x |
ご覧のとおり、マトリックスの乗算や反転などの非常に一般的な(3D)操作は、対応するRTLバージョンのほぼ10倍高速になります。さらに、Fastmathには、膨大な速度の増加のために少し精度を犠牲にする多くのFast*近似関数が含まれています。たとえば、 FastSinCosを使用して4本のサイン関数とコサイン関数を並行して計算すると、RTL SinCos関数を4倍呼び出すよりも最大90倍高速になり、 +/4000ラジアン(OR +/- 230,000度)までの角度に優れた精度を提供します。
32ビットおよび64ビットのデスクトッププラットフォーム(WindowsおよびOS X)で、このパフォーマンスはSSE2命令セットを使用して達成されます。これは、コンピューターがSSE2をサポートする必要があることを意味します。ただし、SSE2は2001年に導入されて以来、今日使用されているコンピューターの大部分がそれをサポートします。すべての64ビットデスクトップコンピューターには、デフォルトでSSE2サポートがあります。ただし、 FM_NOSIMDを使用してこのライブラリをいつでもコンパイルして、SIMDの最適化を無効にし、プレーンパスカルバージョンを使用することができます。これは、Pascalバージョンの速度をSIMD最適化バージョンと比較するのにも役立ちます。
32ビットモバイルプラットフォーム(iOSおよびAndroid)では、SIMDの最適化にはNeon命令セットが使用されます。これは、デバイスがネオンをサポートする必要があることを意味します。しかし、Delphiはすでにこれを必要としているため、これはそれ以上の制限をもたらしません。
64ビットモバイルプラットフォーム(iOS)では、ARM64/AARCH64 SIMD命令セットが使用されます。
iOSシミュレーターのハードウェアアクセラル化サポートはありません(すべての計算にPascalバージョンを使用します)。
単一の精度の浮動小数点値のみでのFASTMATH操作のみ。二重精度の浮動小数点算術は(現在)サポートされていません。
ほとんどの関数は、単一の値(タイプSingle )および2、3次元、および4次元ベクトル( TVector2 、 TVector3 、 TVector4のそれぞれ)で動作します。ベクトルは、空間内のポイントまたは方向を表すために使用されるだけでなく、計算を並列に実行するために使用できる2、3、または4の値の配列と見なすこともできます。フローティングポイントベクトルに加えて、整数値( TIVector2 、 TIVector3 、およびTIVector4 )で動作するベクトルもあります。
2x2、3x3、および4x4マトリックス( TMatrix2 、 TMatrix3 、 TMatrix4と呼ばれる)もサポートされています。デフォルトでは、MatricesはRTLのSystem.Math.Vectorsユニットのように、行の順序で保存されます。ただし、 FM_COLUMN_MAJORの定義でこのレイアウトを変更できます。これにより、マトリックスは代わりに列の順序で保存されます。これは、OpenGLアプリケーションに役立ちます(このレイアウトで最適に機能します)。さらに、この定義は、デフォルトの0..1ではなく、カメラ行列の深さを-1..1にクリップします。繰り返しますが、これはOpenGLアプリケーションのデフォルトに沿ったものです。
3D空間での回転を表すためには、RTLのTQuaternion3Dタイプに似たTQuaternionもあります。
ライブラリの操作は、シェーダー言語(GLSLやHLSLなど)に多少インスピレーションを受けています。これらの言語では、単一の値とベクトルを同様に扱うこともできます。たとえば、 Sin関数を使用して単一のサイン値を計算できますが、 TVector4タイプで使用して1回の呼び出しで4本のサイン値を計算することもできます。前述のように、これはおおよそのFast*関数と組み合わせると、膨大なパフォーマンスが向上する可能性があります。
すべてのベクトルおよびマトリックスタイプは、スカラー、ベクター、マトリックスを無効化、追加、減算、乗算、分割できる過負荷の演算子をサポートします。
また、ベクトルとマトリックスを平等と比較するオーバーロードされた演算子もあります。これらのオペレーターは、正確な一致を確認します(Delphi's = operatorなど)。彼らは非常に小さなバリエーションを許可していません(DelphiのSameValue関数のように)。
算術演算子+ 、 - 、 * 、および/通常、ベクトルに適用するとコンポーネントごとに動作します。たとえば、 AとBがTVector4の場合、 C := A * B (AX * BX, AY * BY, AZ * BZ, AW * BW)にC設定します。ドットまたはクロス製品を実行しません( DotとCross機能を使用してそれらを計算できます)。
マトリックスの場合、 +および-演算子もコンポーネントで動作します。ただし、マトリックスをベクトルまたは他のマトリックスで乗算(または分割)する場合、通常の線形代数乗算(または分割)が使用されます。例えば:
M := M1 * M2線形代数行列の乗算を実行しますV := M1 * V1マトリックス *行ベクトル線形代数乗算を実行しますV := V1 * M1列ベクトル *マトリックス線形代数乗算を実行するマトリックスをコンポーネントに乗るには、 CompMultメソッドを使用できます。
Fastmathは、優れた性能のために独自のベクトルとマトリックスタイプを提供します。それらのほとんどは、Delphi RTLタイプとの機能とデータストレージに同等です。それらの間でタイプキャストするか、fastmathタイプから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 |
| Quaternion | Tquaternion | tquaternion3d |
ドキュメントは、htmlヘルプファイルfastmath.chm in Docディレクトリにあります。
または、オンラインでドキュメントを読むこともできます。
Fastmathリポジトリには、次のディレクトリがあります。
Doc :htmlhelp形式のドキュメント。また、私のデバイス(Core i7デスクトップとiPad3)でパフォーマンステストの結果を含むスプレッドシート(benchmarks.xlsx)も含まれています。DocSource :ドキュメントを生成するためのバッチファイルが含まれています。必要に応じてドキュメントを自分で生成するには、Pasdocexが必要です。FastMath :メインNeslib.FastMathユニットと、プロセッサ固有の最適化を備えたファイル、およびiOSおよびAndroid用のARM最適化バージョンを備えた静的ライブラリが含まれています。Arm :アーム固有のソースコードとスクリプト。Arm32 :ARM Neon最適化機能のアセンブリソースコードが含まれています。Arm64 :ARM64最適化された機能のアセンブリソースコードが含まれています。fastmath-android :Batchファイルとヘルパーファイルが含まれており、Android NDKを使用してAndroidの静的ライブラリを構築します。fastmath-ios :iOS用のユニバーサル静的ライブラリを構築するためのMacOSシェルスクリプトが含まれています。Tests :ユニットテストとパフォーマンステストを実行するFiremonkeyアプリケーションが含まれています。 Fastmathは、簡素化されたBSDライセンスの下でライセンスされています。その機能の一部は、MIT、新しいBSD、ZLIBライセンスの下でライセンスされている他の人のコードに基づいています。これらのライセンスは、プロジェクト全体に使用される簡略化されたBSDライセンスと同じくらい許容されます。
詳細については、license.txtを参照してください。