隠れた高速asin()の存在
49日前原文(16bpp.net)
概要
- PSRayTracingの最適化過程を通じて三角関数近似の検証
- Taylor展開やPadé Approximantによる高速化の試行
- **AIツール(LLM)**から得たアルゴリズムが最良の結果
- 実際のレンダリング速度の比較と効果測定
- 最終的な推奨手法とその評価
PSRayTracingにおける三角関数近似の最適化記録
-
PSRayTracingプロジェクトの最適化過程の記録
-
目標:**asin(x)**の高速かつ十分な精度の近似手法の探索
-
Taylor級数による近似導入、精度と速度のバランスを検証
-
xが**-0.8未満または0.8超の場合、Taylor近似の誤差が大きいためstd::asin()**にフォールバック
-
4次のTaylor展開が最もパフォーマンス良好(+5%高速化)
- C++実装例:
- xの範囲で分岐し、範囲外は標準関数を利用
- 係数を定数で保持し、計算コスト低減
- C++実装例:
Padé Approximantによるさらなる高速化の試み
- Padé Approximantは関数近似の数学的手法
- Pythonで**[3/4]や[5/4]** Padé近似を実装し、Taylor展開と比較
- 誤差が減少し、特に中心付近で精度が向上
- Half Angle Transform(半角変換)を併用し、端の誤差を補正
- |x| > 0.85で半角変換を用い、中心付近でPadé近似を利用
- [1/2] Padéを端の補正用に追加し、さらに計算を簡略化
- C++でも同様のロジックで実装
実際のレンダリング速度比較
-
ベンチマーク環境:M4 Mac Mini, macOS Tahoe, GCC15(-O3最適化)
-
std::asin():約111秒
-
Taylor級数近似:約105秒(約5%高速化)
-
Padé Approximant + 半角補正:約105秒(Taylorと同等)
- 精度は向上したが、速度面で大きな差は見られず
AI(LLM)による最適解の発見
- **Gemini(LLM)**に「C++で使える高速なasin(x)近似は?」と質問
- Nvidia Cg Toolkit由来のMinimax多項式近似を返答
- Horner法による多項式評価+平方根+π/2オフセット
- PythonおよびC++で実装が容易
- 実際のレンダリング速度:約101秒(最速)
- 精度:標準asin関数とほぼ同一、違いは視認できないレベル
- **他環境(Intel i7, Ubuntu, GCC/clang)**でも約1.5倍高速化を確認
結論と推奨手法
-
AIツールから得たMinimax多項式近似が最も高速かつ高精度
-
Taylor級数やPadé Approximantは理論的には有効だが、実装・運用面ではAI提案手法が優秀
-
今後の最適化指針:AIツールの活用と、既存の数学的近似手法の併用検討
-
実装例(C++):
constexpr double HalfPi = 3.1415926535897932385 / 2.0; double fast_asin_cg(const double x) { constexpr double a0 = 1.5707288; constexpr double a1 = -0.2121144; constexpr double a2 = 0.0742610; constexpr double a3 = -0.0187293; const double abs_x = fabs(x); double p = a3 * abs_x + a2; p = p * abs_x + a1; p = p * abs_x + a0; const double x_diff = sqrt(1.0 - abs_x); const double result = HalfPi - (x_diff * p); return copysign(result, x); } -
教訓:最適化前に十分なリサーチを行い、既存の知見やツールを活用することの重要性