简介:一个对世界抱有好奇的人为了能回答清楚这个问题,我们先来开一个脑洞:如果从这个角度来考虑,对于这个问题我可以提供一个有趣的思路。既然已经提到了现实世界的数值精度问题,那么我们身处在这个黑客帝国世界里,怎样才能感知到世界底层正在进行的数值计算过程,从而还进一步能了解到其浮点运算的特性呢?其实,我们可以从我们自己构建过的虚拟世界的创造者的角度来同理思考这个问题。人类构建的最多的虚拟世界是什么呢?答案是3...
一个对世界抱有好奇的人
为了能回答清楚这个问题,我们先来开一个脑洞:
如果从这个角度来考虑,对于这个问题我可以提供一个有趣的思路。
既然已经提到了现实世界的数值精度问题,那么我们身处在这个黑客帝国世界里,怎样才能感知到世界底层正在进行的数值计算过程,从而还进一步能了解到其浮点运算的特性呢?
其实,我们可以从我们自己构建过的虚拟世界的创造者的角度来同理思考这个问题。
人类构建的最多的虚拟世界是什么呢?
答案是 3D 游戏,尤其是 3D 的 MMORPG(网络多人角色扮演)类别的游戏。
虽然人类现在创造的 3D MMO 游戏还很简陋,离真正的「黑客帝国」还差很远,但是某些特性还是有可类比性的。
假如我们在一个 3D 游戏中,要如何了解这个游戏浮点方面的特性?
虽然身为玩家,我们没办法了解游戏底层的计算过程,但是我们可以观察到与浮点计算有关的一些画面表现,比如说游戏引擎在处理模型细节方面的表现来分析运算精度方面是否有问题。
在 3D 游戏中,所有的画面渲染和三维计算都是用浮点方式进行计算的,这种计算非常消耗系统的资源,所以硬件厂商为这种计算,专门设计了具有强大浮点计算能力的 GPU 芯片的显卡来专司这方面的计算需求,但是好的程序员还是会非常谨慎地优化算法,力求节省计算资源,以免造成系统的卡顿。
在 3D 游戏中,有一个很重要的优化算法的地方就是游戏的空间碰撞问题。
说白了就是 3D 物体的碰撞检测,简单来说,就是判断游戏里两个物体有没有碰撞,举个简单例子:
上面是游戏世界中的两个小球,如何判断它们有没有碰撞呢?
这用初中数学知识马上就可以知道。
计算圆心之间的距离 d 和两球半径和 r1+r2,如果 d<=r1+r 就说明发生了碰撞。
三维坐标系中,距离 d 可以用距离公式计算,超简单是不?
但是如果有三个物体呢,那就麻烦一点,需要两两比较,做 3 次计算,四个物体自然做 6 次运算。
但是如果有 100 个物体呢,那我们就需要 5000 次的计算了,在游戏中往往会有更多的运动物体需要计算,而且这些物体的形状往往是非常不规则的,比如墙壁、河流、树木、人物、武器等等,那么这些计算量就马上指数上升起来。
这时候,程序员就需要运用各种算法技巧来减少运算量,比如四叉树:
当然,就算有了这些方法,我们也要不能无限精度地计算距离,当两个物体挨得很近的时候,出于计算量的考虑,我们一般把浮点精度都控制在一定范围内。
那么控制了计算精度以后会发生什么事情呢?
如果出现了碰撞检测精度不足的情况,往往就会出现一定的显示 BUG,这种 BUG 就叫作「穿模」。
服装穿模
3D 游戏中的慢速运动下的静态穿模 BUG 主要有两种因素引起:
一种是类似上图的模型设置问题,有些模型并没有检测碰撞;
还有一种则物体模型过小,碰撞检测精度不足,比如两个角色站太近,手持的武器就穿模到对方身体里了。
这个极近距离的碰撞检测精度就和游戏的浮点特性非常相关了,理论上如果游戏里碰撞精度能计算到最小的像素的话,是不会出现这种穿模现象的,但是这样做的开销太大了,所以一般程序员也就容忍游戏出现一些这种显示上的小 BUG,反正对玩家游戏体验影响也不太大。
但是我们很清楚,这种现象出现的本质就是因为游戏引擎里碰撞算法的浮点精度不足造成的。
那么,在现实世界里,我们能观察到类似的现象吗?
还真的能,在量子物理学里就有一个非常类似的现象——「量子隧穿」。
所谓量子隧穿,就是微观粒子在非常靠近一个屏障(高能位势垒)的时候,某种情况下会凭空直接穿越屏障跑到对面去的现象。这种现象,在宏观世界、经典物理学体系下是绝对不可能发生的,但是在微观世界、在尺度小到一定程度的时候却会出现。这用传统的经典物理学是完全无法解释的。
在正常认知里,一个小球想要穿过哪怕是极薄的纸,也不可能既不付出任何能量,也不弄破这张纸。可是在量子世界里,粒子就是这样诡异地越过了足够薄的障碍。
量子物理学对此的解释也非常晦涩。
量子物理以微观粒子的位置和能量具备不确定性来进行解释:量子具有一些不确定的能量涨落,偶尔它们可以从虚无中凭空「借」到了一些外界能量,然后借助这些能量就越过了墙壁,从而实现了凭空穿墙。
这听起来是不是非常玄幻?
但是,这个现象的的确确真实存在,甚至人们已经利用该现象开发出了很多实用的高科技设备,比如隧道扫描电子显微镜等等。
而这个现象的副作用则是大大影响了我们对微观世界的掌控。比如在微电子行业里,也正是因为存在量子的隧穿效应,才导致现在的微电子芯片技术发展到 1nm 时代就碰上了继续缩小尺寸的物理学障碍。芯片里阻隔电子的材料如果尺寸小到 5nm 以下,量子隧穿效应导致的漏电现象就不可忽视了,如果尺寸进一步减小,那么漏电问题将更加严重,电子会随机的穿越过薄的栅极,从而导致芯片的逻辑电路无法正常工作。
而这个问题已经成为芯片技术继续发展需要克服的最大障碍了。
这听起来像不像 3D 游戏里的细小物体的穿模 BUG,当物体小的一定程度的时候,因为碰撞检测算法的浮点计算精度不足,所以细小物体在靠近墙壁时候,偶尔就会穿透到墙壁或者物件里面去一样。
理论上,如果微观世界采用和宏观世界一样的碰撞算法的话,只要计算精度足够,是应该不会出现这种现象的。
比如说,计算精度达到普朗克尺度,那么绝对就不可能出现隧穿现象了。
而且,从隧穿发生的尺度来看,其实距离普朗克尺度还非常遥远,出现隧穿现象的尺度我们按 1nm= 1E-9m 算,而普朗克尺寸大约是 1.6E-35m,两者竟然相差了 26 个数量级之多!
可见,我们这个宇宙的计算精度有多低!
最后,为了证明我们这种离谱的理解方式有效,我们来看一个量子隧穿中非常难以理解的问题。
隧穿效应里面最难以解释的现象是:「超光速隧穿」。
根据量子理论中能量时间的不确定性原理,量子穿越屏障的时间和屏障的能垒高度是成反比的,也就是说,屏障能量越高,穿越时间反而越短,如果这个屏障的宽度足够的话,那么足够高能的屏障就会导致粒子以穿越光速的速度穿过了屏障,这和相对论中指出的光速是宇宙最大速度就冲突了。
理论物理学家们就这个现象争论不休,并且提出了各种各样的新的假设和说法来解释这个现象,试图一方面要坚决捍卫光速是宇宙速度绝对上限的地位,另一方面又要能解释出量子超光速穿墙的现象是咋回事。这些先进理论弯弯绕绕复杂无比,一般人建议不要去了解,以免出现头脑过载的症状。
所以我们这些凡人还是回到地面来,想想看怎么用我们初中二年级的水平来理解这个最尖端的科学问题吧。
我们来虚拟一段场景对话:
比如,你是某个网络赛车游戏公司的老板,今天你很生气,因为游戏里某条赛道的最新成绩被刷新到了一个恐怖的令人惊奇的地步,有玩家只用了几秒钟就完成了比赛,很显然这是游戏出现 BUG 被人利用了,于是你叫来了游戏的运营经理和研发经理开会。
「你们谁来跟我解释一下,这个变态的成绩玩家是怎样做到的?」你作为老板有权要求下属们给你一个合理的解释。
运营经理连忙回答:「我了解过了,这是玩家利用 BUG 实现的。」
研发经理感觉很奇怪,说到:「应该不可能啊,这种 BUG 理论上是不可能出现的。」
于是你问道:「为什么不可能出现呢?」
研发经理说:「因为我们游戏里的赛车其实是有速度上限的,无论玩家怎样改装赛车,都不可能超过这个速度上限。」
「为什么不可能超过上限呢?难道玩家没有某种手段绕过这个限制吗?」
「不可能绕过的,因为这个速度上限并不是我们为了防止玩家刷 BUG 设置的,而是我们游戏的底层机制决定的。因为赛车在我们游戏里运动需要不断地改变位置,而我们游戏里面物体改变位置的最小单位和最小时间单位都是确定的,所以从理论上就会有一个最大速度,玩家无论用什么办法都不可能让赛车超过这个速度。因为这个速度就是我们游戏能保证赛车连续运动的极限,再快,赛车在玩家眼里就会出现瞬移了,这种现象从我们的底层算法上就是无法出现的,我们的赛车在程序空间中,只能一格一格的移动,不能跳格!」
你听完,觉得研发经理说得很有道理,于是就非常疑惑地问运营经理:「那么我们的玩家是怎么做到的呢?」
运营经理说:「我也不太懂这个原理,但是我能把玩家的操作重现给你们看。」
于是运营经理进入游戏,选择赛道开始比赛。只见运营经理在赛道上找到一个合适的位置,飞快地把车撞进了路边的一个崖壁,经理试了几次后成功了。某一次几乎是一瞬间,车没有被崖壁正常地弹回去,而是从另外一边的崖壁被飞快地弹了出来,这个穿越过程似乎没有花费任何时间,于是经理就重现出了玩家的变态成绩。
办公室里一阵寂静,你和研发经理两人面面相觑。
研发经理毕竟是 211 毕业的高材生,他想了一会就恍然大悟道:「原来是这样,我实在没有想到会出现这种情况,这其实是赛道旁边的崖壁太薄了造成的。」
「崖壁太薄为什么造成这个 BUG?」你一脸的疑惑。
「是这样的」,研发经理已经完全理解了问题所在:「我们游戏里面的碰撞检测是有时间间隔的,程序会每隔一会检测赛车模型的中心和各种阻挡物之间的距离关系,一旦距离小于某个值就会视作发生碰撞,将车弹回去。但是这个崖壁阻挡太薄了,玩家的车速高到某个程度的时候,撞进来又正好在两次检测的空隙之间的时候,车的中心就穿过了这个崖壁才被检测到碰撞,但是因为模型已经越过了崖壁,于是碰撞程序就把车移到了另一边,所以赛车就穿墙而过了。这个移动是碰撞算法造成的,和正常的移动不一样,所以没有受最小移动距离的限制,所以就超过了游戏的最高车速。」
「碰撞算法有这么高的能力,能帮助赛车超过游戏的最高运动速度?」
「是的,游戏设置最高运动速度的底层原因是因为物体不能在空间中超过最小单位作跳跃,否则就会出现瞬移,如果有瞬移现象,那么就可能出现两个物体同时瞬移到同一个位置的可能。所以要求物体连续运动的本质上也是避免不同物体会同时出现在同一个最小空间单位里。但是,碰撞算法的底层原因也是为了避免不同的物体同时出现在同一个空间里,所以,游戏存在最高速度其实并不是原因或者目的,而是只是现象,更本质底层机制的其实避免不同物体的空间重叠,所以一旦出现这种空间重叠,这时候弹出物体几乎是不需要所谓速度的,系统会以最快的节奏把模型瞬移出去。当然,也不是完全无时间消耗的瞬移,重新绘制物体还是要花费一点时间的,但这也远超最高速度了。
「哦」,你和运营经理总算弄明白了这个 BUG 的底层原因,于是你又问道:「那我们要怎样避免玩家再利用这个 BUG 呢?」
研发经理想了一下说:「很简单,把墙加厚点就行了。」
运营经理有点质疑:「这好像没有从本质上解决问题吧?」
研发经理耸耸肩:「这就是最省事的办法了,如果你觉得要从底层来彻底解决这个问题的话,首先我觉得没必要,因为减小检测间隔会极大的增加系统的负担,需要买更强大更贵的服务器,而且绝大多数情况下对玩家体验也不带来什么明显改善。其次,修改底层算法风险很大,搞不好会把整个游戏搞宕机,老板你看呢?」
「去让关卡策划和美术把崖壁改厚点,顺便检查下还有没有其他赛道需要修改。」你感觉作为老板,决策起来一点难度都没有。
在结束会议之前,你有点不放心,又问了下研发经理:「你确定崖壁改厚了,就不会再出现这个 BUG 了吧。」
研发经理一看就是一个很严谨的人,他斟酌了一会说:「理论上,还是有穿过的几率,因为我们的检测时间也有随机性,只要玩家尝试的次数足够多,再厚的阻挡也有穿过的概率,只是这个概率极小极小。」
「好吧,那就这样吧」,你作为老板深刻地理解不要为极小概率的事情去发愁的简单道理,这种问题,留给知友们去操心就好了。
虽然上面的场景对话是我虚拟出来的情节,但是大家应该明白这段对话指的是什么意思。
从上面程序员和老板的对话中,其实我们得到了一个非常惊人地看待宇宙基础规律的视角,比如我们可以不把光速是当前时空速度上限当作是一种最底层的初始规律,而是把它视作一种现象,那么这个宇宙必然还有更底层的规律导致了这种现象的出现。
除了光速,我们甚至可以用类似的角度来看待物理学中的各种基础常数,尤其是那些有量纲的常数,它们很可能不是绝对不变的宇宙初始变量,而只是某些更底层的物理规律导致的一种结果。比如电子的电荷数值,或者质子的质量等等。
从另一方面来想,既然我们感觉常数之上还有更底层的规律,那么常数绝对不变也不是那么不可挑战了。
就好像光速问题,虽然在底层上有普朗克长度和时间做为计算基础,但是更基础的约束法则很可能来自宇宙要绝对避免不同物质在相同时空的重叠可能,那么在某些特殊的情况下(比如为解决量子尺度运算精度不足造成的重叠 BUG 进行的紧急操作),这个光速限制就有可能是会被打破的,这也体现了一种很容易理解的程序思维:下层逻辑必须服从上层逻辑的约束。
最后回到问题吧,我们既然可以把量子的隧穿效应想象成世界运算的精度 BUG,那么实际上就已经推算证明了我们这个世界底层的浮点运算是具有输出精度范围的。
这说明我们这个世界在底层运算中并不能以最小的尺度精确地表达每一个粒子在每一时刻的精确位置和状态,而是用一种被大幅度舍弃浮点精度后的结果来大致表达粒子各种状态而已,而且这些输出结果互相制约,这个测量特性正是在物理学上经常被人提起的「测不准原理」:当你企图得到粒子更精确的位置数值的时候,那么你就无法得到粒子的精确运动数值(速度)。
我们只能认为这就是我们世界底层算法造成的固有特性,我们世界的创造者(或者说程序员)在构造我们世界的底层算法的时候,可能出于节省资源的考虑,大幅度地缩减了粒子运动算法的输出精度,采用了一种微观概率输出的方式来解决宏观世界精确表达,如果这的确是出于节省硬件资源的目的的话,作为一名程序员同行,我需要表达由衷的赞叹:漂亮而又实用的算法!
这个节约资源的底层算法想必是我们世界能正常运行在现有主机上的原因,当然也是造成量子世界里各种诡异的实验结果的原因所在,比如:波粒二象性问题、延迟选择实验、光子全同性问题、粒子自旋问题、量子纠缠效应等等。
我们如果能真正弄清这个底层算法的本质,想必对了解我们这个世界会有极大的帮助吧,希望有一天,我们能揭开造物主所隐藏起来的真相。
本篇作者:阿布大树
备案号:YX11mENWlwK
来自盐选专栏《听赛先生的话:漫游数理世界》