数值计算 --- 平方根倒数快速算法(上)

平方根倒数快速算法(上) --- 向Greg Walsh致敬!

写在最前面 --- 一场关于平方根倒数快速算法作者的讨论:

        上图中的这段代码出自一个早期的3D游戏<雷神之锤>的源代码,它实现的功能就是计算一个数x的平方根的倒数:

1/\sqrt{x}

        这段代码之所以称之为经典,私以为主要是因为以下几点原因:

                1,这段代码是出自于程序员大神John Carmack之手(实际上是另有其人:Greg Walsh)。

                2,这段代码之简洁,且计算速度非常快。

                3,这段代码中John Carmack遗留下来的那句锐评论“what the fuck”。这里,我把他翻译成“这是什么鬼?!!!”

                4,这代码中神秘的magic number“5F3759DF”究竟是干什么的?

        为了彻底的弄明白这些问题,比如说那个magic number是什么,怎么来的,有什么用?还有为什么这个算法的计算速度如此之快,精度如此之高,等等。我查阅了一些相关资料和视频。下面是我自己的总结,作为我对这段代码的学习备忘录。

        By the way:那有人要说了,这都2024年了,为什么还要研究这个算法。根据我自己的学习体会,我觉得主要就是兴趣。再其次就是这段代码从最初被创作到现已经过去这么多年了,被研究已经比较充分了。因此,在网上能够查到的相应资料很多,更有利于个人学习,再加上现在有了chatGPT的加持:)。当年很多不太清楚的地方,在后面这些年中也因为大家的钻研变得慢慢清晰了,尤其是这段代码的原作者(Greg Walsh)究竟是谁的争论,也是直到2007年随着大家的激烈讨论才逐渐浮出水面的!下面的这个名为Beyond3D的外国论坛记录了当年的讨论,以及这段代码的原作者出现的过程。


是John Carmack或Michael Abrash吗?

       在讨论之前提到的《Doom3》引擎中 NV40 的渲染路径时,这段代码被提到并归因于 John Carmack;他是显而易见的选择,因为它出现在他引擎的源代码中。Michael Abrash 也被认为可能是作者。Michael 以 x86 汇编优化专家的身份脱颖而出,他撰写了传奇的《Zen of Assembly Language》和《Zen of Graphics Programming》等书,并且在《Quake》开发期间与 John 一起工作,负责优化当时的 CPU 上的 Quake 软件渲染器。

        为了确定这段代码的究竟是不是他写的,有人写信问他,于是就有了下面的这段问答。(这一讨论发生在2004年)

上述回信的翻译:

你好,John,

Beyond3D.com 论坛上正在讨论这个问题,谁是以下代码的作者:

        这可以归因于你吗?分析显示它的原理极其巧妙,据说来自 Quake 3 的源代码。 大多数人说这是你的作品,也有人说是 Michael Abrash 的。你知道是谁写的吗?可以讲一下它的历史吗?

不是我,我也不认为是 Michael。也许是 Terje Mathison?

John Carmack


是Terje Mathisen吗? 

        尽管John Carmack在他的回信中否认自己是这段代码的作者,同时他也不认为这段代码出自Michael Abrash之手。但他提到了另一个可能的线索/可能的作者Terje Mathison,但随后针对这一问题的讨论便没了下文。

       直到最近(时间来了2005年的八月),John 在今年的 QuakeCon 演讲中提到完全开源 Quake 3 v1.32 源代码,包括 3D 渲染器,得到了在场观众的热烈欢呼。随着《Doom3》的发布并赢得了好评,黑客们开始关注 id 公司,问 Quake 3 这个相对较古老的渲染器什么时候可以供人们学习和使用。

        QuakeCon 后的一周,Quake 3 源代码被正式公开,Slashdot 也报道了这个显而易见的新闻,并再次提到了快速近似倒数平方根代码的作者问题。很快我想到了 Terje,但当时却忘了问他!

        Terje Mathisen是 x86 汇编语言优化领域的大师之一。回到 3D 图形的早期软件优化时代,像 Michael、Terje(当然还有 John)这样的人会花费大量时间对关键的性能代码进行手写汇编优化。这个投资在《Doom》和《Quake》的时代取得了显著的回报。你可以在 comp.lang.asm.x86 中看到 Terje 分享的建议、优化、轶事和代码片段,这个人不是一般的厉害。那么Terje是真正的作者吗?

上述回信的翻译: 

Ryszard 写道:

嘿 Terje,

自从 id 公司公开了 Quake 3 Arena 源代码后,这个问题再次出现。

你是写出这个快速倒数平方根实现的人吗?如果是,你能讲讲它的来历和你如何想出这个算法吗?一大批黑客和极客都想知道这个问题。由于 John 说不是他,可能也不是 Michael,那是你吗?

        你好,Ryszard,还有你好 John,好几年没见了。:-(

        谢谢你把我列为可能的作者,当我第一次看到这个问题时,我确实以为这是我写的代码。:-)

        五年前,我确实为了帮助一位瑞典朋友解决流体化学计算问题,写过一个非常快速且准确的invsqrt()函数。这使得他的模拟运行时间从原来的一周缩短到了一半,且能保证8-10位有效的数字。

        然而,文中的代码却不是我写的,我猜它的准确度应该只有百分之一以内?瑞典朋友需要至少 48 位有效位的精度,为此我采用了更直接的查表法和牛顿拉夫逊迭代法。由于水分子包含三个原子,我可以同时计算三个invsqrt()值,从而避免了 FP 流水线中几乎所有的气泡。

        不过,我感觉Q3A的代码风格更类似于MIT的HAKMEM文件中的一些代码。:-)

Terje


是Gary Tarolli吗?

        这样看来Terje也不是真正的作者,尽管如此,我们也在他的回信中看到了他的实力。他基于查表法和NR迭代法所写的invsqrt()汇编版的精度达到了惊人的48位。而且他回忆说,这些代码的风格类似于 MIT 的 HAKMEM 文档中的代码。

        随着John CarmackTerje Mathisen都否定了他们是平方根倒数快速算法这段代码的作者,且Michael Abrash也间接被否定了,看来要想找到原作者似乎需要另谋出路。通过 Google搜索,我们发现NVIDIA也可能与之有关,并找到了一篇提到了NVIDIA的某位员工---Slashdot的文章。经过一番询问,我们得知 3dfx 的创始人之一Gary Tarolli是最有可能知道这段代码来源的人。

        因此,我又向 Gary 发了一封邮件,询问他是否是本代码的作者?

上述回信的翻译: 

         

一段过去的记忆!(时间来了2005年的九月)

我确实认得下面的代码,但这不是我的功劳。

我记得大约十年前碰巧看到过它,我当时还重新推导过它。这是牛顿-拉夫逊迭代法,加上个非常巧妙的近似初值。

        我记得我当时尝试过除了0x5f3759df的其他值。我可能是在IRIS Indigo做了与之相关的工作,或者是为Kubota咨询时而做的,我现在不太确定了。

        鉴于它所执行的数学运算量

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

松下J27

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值