最近读高观点下的数学这本书,对书中介绍的布劳威尔不动点定理的有趣性质印象很深,原因是这个定理的某些性质能够解释我们生活中的一些常见现象,这里结合一个例题加以分析,然后介绍这个定理的思想在计算机系统页表映射中的应用,聊以记录。
从一个数学题讲起:
f(x)是定义在[0,1]上的连续函数,并且0<=f(x)<=1.求证:至少存在一个ξ,使得f(ξ)=ξ;
证明过程比较简单,构造函数:
F(x)=f(x)-x
则,F(0)=f(0)-0 >=0, F(1)=f(1)-1<=0.
根据零点定理,函数F(x)在闭区间[0,1]上连续,且F(0)与 F(1)异号(即F(a)× F(b)<0),那么在开区间(a,b)内至少有函数F(x)的一个零点,即至少有一点ξ(0<ξ<1)使F(ξ)=0. 得证。
上面的例子拓展一下,给定函数f(x),那么就把满足f(x)=x这样的x称为不动点,其实就是题目中的ξ,有的函数有不动点,有的函数就没有不动点,比如下面的函数有不动点:
但是如下的函数y=x^2+0.8却没有不动点:
那么什么样的函数会有不动点呢?我们从几何图形的角度反思一下刚才的题目,所谓满足f(x)=x的点,其实就是y=f(x)的图像与y=x这条直线的交点,在这个题目中,f(x)的定义域在[0,1]时,值域也是[0,1].所以,你的f(x)不管怎么画,只要它是连续的,必然会和正方形的对角线有1个交点,这个交点就是不动点:
把上面的信息提取出来,就得到了布劳威尔定理的一维情景:f(x)是定义在闭区间I上的连续函数,如果它的值域也包含在I中,则它至少存在一个不动点,这个定理对于多维空间也是适用的。
可以用牛顿数值计算法找到这个不动点:
上图寻找不动点的轨迹在不动点两侧呈现出左吸右拉的特点,具体的说,在(-∞,0)时,寻找轨迹发散,无法找到不动点,但是在[0,不动点]区间,轨迹收敛于不动点,同样,[不动点,1]区间收敛,但是(1,∞)又开始发散,所以看起来围绕不动点的[0,1]区间有点类似于黑洞视界,主要进入它的势力范围,马上被吸入不动点,否则则是发散到无穷远处。
上面介绍的是不动点定理的一维情景,不动点定理同样适用于高维空间,我们生活中遇到最多的应用情况就是不动点定理在2维空间中的应用,用公式表示就是:
f(x,y) = (x,y)
典型的应用场景举例:
1.桌面上放着一张和桌面大小形状一样的白纸,我们把它拿起来,揉成团,再仍回桌面,那么就可以断言,这张纸团上一定至少存在一个点,这个点在桌面上的投影和这个点在纸张展平状态下的位置重合。
2.我们去商场或者旅游经典经常会看到场所的导航牌,上面绘制了游览区域的二维平面地图,地图中用红色几何图形标志了你当前所在的位置。其实这幅图之所以能够绘制出来,全拜不动点定理所赐。
3.任何的地图导航软件,都有一个功能,标记你当前所在的位置在地图上位置表示,并且伴随着你的移动而移动,这个点能够绘制出来,也是由不动点定理的正确性保证的。
园区地图的例子:
地图举例:
这个定理的证明非常复杂,涉及到拓扑学,非数学专业本硕阶段都不会涉及。这里只用geogebra直观演示一下的有趣指出,以地图导航为例,在中国地图上找到不动点的位置:
因为两张地图是一个正比的满射,原理推导比较简单,如下图所示,不再赘述。
可以根据方程与直线交点的关系,算出不动点的坐标
解方程的应用-迭代法
不动点定理也是迭代法的基础,设X是一个空间,映射ƒ:Χ→Χ 把每两点的距离至少压缩λ倍,即d(ƒ(x),ƒ(y))≤λd(x,y),λ是一个小于1的常数,那么ƒ必有而且只有一个不动点,而且从Χ的任何点x0出发作出序列x1=ƒ(x0),x2=ƒ(x1),...,xn=ƒ(xn-1)...,这序列一定收敛到那个不动点。这条定理是许多种方程解的存在性、惟一性及迭代解法的理论基础。
做一个不太恰当的比喻,比如你手中拿着一个气球,气球在不停的放气导致体积越来越小,如果在放气过程中,气球保持原来的空间位置不变,那么在放气的过程中,一定始终存在一个位置,这个位置在气球放气前后始终保持不变。想要算出这个位置也很容易,只要在原始气球空间内随便找到一个点,代入f,由于f是一个不断缩小的映射,得到的的结果会比原来的值小,在把新得到的值不断代入f,得到的结果将不断逼近于最终的不动点。
北方的朋友家里都会蒸馒头,蒸馒头用的面团经过发酵后膨胀,只要面盆没有移动过位置,你就可以说,这个面团中一定有一点,在发酵前后的位置是不变的。而且也可以根据迭代法算出这个点。
在计算机系统中的应用
虚拟化内存的通用思路:https://www.kernel.org/doc/ols/2007/ols2007v1-pages-225-230.pdf
- A radix tree ,the page table, encoding the virtualto-physical translation. This tree is provided by system software on physical memory, but is rooted in a hardware register (the cr3 register).
- A mechanism to notify system software of missing translations (page faults).
- An on-chip cache (the translation lookaside buffer, or tlb) that accelerates lookups of the page table.
- Instructions for switching the translation root in order to provide independent address spaces.
- Instructions for managing the tlb.
这种自身的一部分到自身的映射,颇有点像计算机系统中存在于内存的PAGE TABLE到其容器-整个Memory的映射,既然如此,在页表类似中,应该也存在不动点,简单起见,以一个虚拟地址为11BIT的两级映射模型为例说明,示意图如下图。
指针宽度小于等于计算机的字长,模型定义的指针为11位,所以定义模型字长为16位,PGD位于PFN 1,PGD的ENTRY 0指向下级PTE,位置在PFN3,PTE的ENTRY 1映射到自身PFN3,所以PFN3中的PTE ENTRY2就是那个不动点,作为一个PTE ENTRY,它映射的页框自身就是它所在的位置,如同公园导航地图中的情况,你恰好在这里。
另外,也可以总结出,只有最后一级页表PTE具有这种再指向自身的能力,因为PTE定义的下级页框并未定义使用方式,而如果是上级页表,则强行定义了下级页表的格式,所以,对于PTE来说,顶多映射后的虚拟地址为占用状态(占用作为PTE TABLE),而并没有格式要求,对于PGD来说,加入PGD ENTRY 3重新映射回自身,但是作为PGD的下级,必须是PTE表,那这个PFN到底是PGD呢还是下级PTE呢?就会起冲突。
页目录大小和PAGE SIZE并没有绝对关系,PAGE_SIZE为4K,并不要求中间页表项一定要小于等于4K,也可以大于PAGE SIZE。比如上面的例子,如果把前面的两级合为1级,一共有6个BIT,每个项目2个字节,所以表项为128字节,大于页面大小32字节。
同理,页表也可以小于PAGE SIZE,比如ARM的 segment映射,使用一级页表,页表16K,一共4K条目,每个条目映射1M,总共映射4G,页表大小16K远远小于 1M的PAGE SIZE。
如果将页表存储在一个独立的存储器上去映射主存,比较容易接受,但是如上面所分析,这两种情况是等价的。就如同你在国内看中国地图,和在国外看中国地图,都不会有阻碍一样。唯一的区别是,页表存在于独立存储器上时,不存在不动点。
关于指针长度和字长
大学学微机原理从8086开始学的,8086比较奇葩,它的地址总线是20位,数据总线是16位,用现在比较时髦的话术描述,它应该属于一个真16位系统,数据总线和地址总线的不一致,导致CPU内核发出去的地址无法直接访问完整个20位的地址空间,所以设计了段机制,通过段和数据总线16位的组合成20位的物理地址。所以,这个时候,CPU发出去的16为指针是不能直接使用的,必须和段选择子结合在一起才能发到地址总线上。这个时候,指针长度等于字长16位。
随后,INTEL新的处理器改变了设计,处理器的数据总线和地址总线宽度变的一致了,这样在也不用短选择子这个鸡肋的设计了。所以,目前的INTEL处理器,指针和字长仍然是一致的。但是由于64位的指针过长,导致CACHE利用率低,有的时候不需要这样长的指针设计,所以配合编译器又出现了ILP32等应用方式,指针的长度可以小于字长。