0

0

C++如何利用位运算实现高精度的快速倒数平方根算法?(图形学底层优化)

穿越時空

穿越時空

发布时间:2026-03-13 15:29:41

|

628人浏览过

|

来源于php中文网

原创

c++如何利用位运算实现高精度的快速倒数平方根算法?(图形学底层优化)

为什么不用 1.0f / sqrtf(x) 而要手写位运算倒数平方根?

因为图形管线里每帧要算成千上万个 1.0f / sqrtf(x),而标准库的 sqrtf 是 IEEE 754 完全精度实现,耗时高;GPU 早期用的 rsqrt 指令本质就是这个位运算 trick 的硬件化。它不求精确值,只保证相对误差 sqrtf 的 3–5 倍。

核心思路:把 float 当作整数读出来,做一次位移和减法,再转回 float,最后用牛顿迭代修正一次 —— 这就是著名的 “Quake III Arena” 里的 Q_rsqrt

  • 只适用于 float(32 位),double 不行 —— 位模式长度和 magic number 都不同
  • 输入必须 > 0,且不能是 denormal 数(如 1e-40f),否则整数 reinterpret 会崩
  • magic number 0x5f3759df 是对函数 f(y) = y⁻¹ᐟ² 在 log-space 上的最优仿射逼近结果,不是随便写的

Q_rsqrt 的标准实现与关键参数解释

这是最稳定、被验证过的版本,直接可用:

float Q_rsqrt(float number) {
    long i;
    float x2, y;
    const float threehalfs = 1.5F;
<pre class='brush:php;toolbar:false;'>x2 = number * 0.5F;
y  = number;
i  = *(long*)&y;                       // 把 float 的内存按 long 解释
i  = 0x5f3759df - (i >> 1);           // 关键位运算:右移1位相当于指数/2,再用 magic 减
y  = *(float*)&i;                      // 转回 float,此时 y ≈ 1/sqrt(number)
y  = y * (threehalfs - (x2 * y * y));   // 一次牛顿迭代:y ← y × (1.5 − x/2 × y²)
return y;

}

立即学习C++免费学习笔记(深入)”;

注意几个硬约束:

零沫AI工具导航
零沫AI工具导航

零沫AI工具导航-AI导航新标杆,探索全球实用AI工具

下载
  • *(long*)&y 依赖小端 + sizeof(long) == 4,在 64 位 Linux/macOS 上 long 可能是 8 字节 → 必须改用 int32_tstd::bit_cast(C++20)
  • 右移用的是算术右移还是逻辑右移?对负数有影响,但这里 y > 0,最高位是符号位=0,所以 >> 1 安全
  • 牛顿迭代只做一次:够用且性价比最高;两次虽更准,但开销翻倍,实际图形渲染中完全没必要

现代 C++ 中怎么安全又高效地写?别碰指针别踩 strict aliasing

直接类型双关(*(long*)&y)触发 undefined behavior(UB),GCC/Clang -O2 下可能优化出错。正确做法:

  • std::bit_cast<int32_t>(y)(C++20)—— 最干净,无 UB,编译器通常生成相同汇编
  • memcpy(&i, &y, sizeof(i)) —— C++11 起就安全,主流编译器会优化成 mov 指令
  • 绝对不要用 union hack,C++ 标准未保证 active member 切换后旧成员的 bit 表示仍有效

示例(C++20):

#include <bit>
float fast_rsqrt(float x) {
    auto i = std::bit_cast<int32_t>(x);
    i = 0x5f3759df - (i >> 1);
    float y = std::bit_cast<float>(i);
    return y * (1.5f - (x * 0.5f) * y * y);
}

哪些场景下这算法会失效或变慢?

它不是万能加速器,用错地方反而拖累性能:

  • 输入接近 0(比如 1e-38f)→ 对应的指数域极小,右移后 magic 减法溢出,结果为 NaN 或极大数
  • 编译器开了 -ffast-math 时,sqrtf 本身可能已被替换成近似指令,此时 Q_rsqrt 优势消失,甚至因额外分支/指令更多而更慢
  • 在 ARM64 或现代 x86-64 上,rsqrtps 指令延迟仅 3–4 cycle,比手写 C++ 版本还快 —— 直接内联汇编或用 __builtin_ia32_rsqrtps 更合适
  • 如果只需要一次倒数平方根,且不处于 tight loop 中,老老实实用 1.0f / sqrtf(x),可读性、可维护性、跨平台性都更好

真正值得手写的,是那种每帧调用十万次以上、输入范围可控(如单位向量归一化)、且 profiling 确认它是瓶颈的内层循环。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
css中float用法
css中float用法

css中float属性允许元素脱离文档流并沿其父元素边缘排列,用于创建并排列、对齐文本图像、浮动菜单边栏和重叠元素。想了解更多float的相关内容,可以阅读本专题下面的文章。

595

2024.04.28

C++中int、float和double的区别
C++中int、float和double的区别

本专题整合了c++中int和double的区别,阅读专题下面的文章了解更多详细内容。

108

2025.10.23

c语言union的用法
c语言union的用法

c语言union的用法是一种特殊的数据类型,它允许在相同的内存位置存储不同的数据类型,union的使用可以帮助我们节省内存空间,并且可以方便地在不同的数据类型之间进行转换。使用union时需要注意对应的成员是有效的,并且只能同时访问一个成员。本专题为大家提供union相关的文章、下载、课程内容,供大家免费下载体验。

129

2023.09.27

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

334

2025.08.29

C++中int、float和double的区别
C++中int、float和double的区别

本专题整合了c++中int和double的区别,阅读专题下面的文章了解更多详细内容。

108

2025.10.23

undefined是什么
undefined是什么

undefined是代表一个值或变量不存在或未定义的状态。它可以作为默认值来判断一个变量是否已经被赋值,也可以用于设置默认参数值。尽管在不同的编程语言中,undefined可能具有不同的含义和用法,但理解undefined的概念可以帮助我们更好地理解和编写程序。本专题为大家提供undefined相关的各种文章、以及下载和课程。

6500

2023.07.31

网页undefined是什么意思
网页undefined是什么意思

网页undefined是指页面出现了未知错误的意思,提示undefined一般是在开发网站的时候定义不正确或是转换不正确,或是找不到定义才会提示undefined未定义这个错误。想了解更多的相关内容,可以阅读本专题下面的文章。

3344

2024.08.14

网页undefined啥意思
网页undefined啥意思

本专题整合了undefined相关内容,阅读下面的文章了解更多详细内容。后续继续更新。

1687

2025.12.25

TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

26

2026.03.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 11.3万人学习

C 教程
C 教程

共75课时 | 5.4万人学习

C++教程
C++教程

共115课时 | 21.7万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号