为什么内存空间分配总是以64K为边界?
admin
2021-01-17 05:39:34
0

原标题:为什么内存空间分配总是以64K为边界?

有时候你可能会有这样的疑惑:为什么页面大小是4K,而VirtualAlloc函数分配的内存是以64K(而不是4K)为边界呢?

事情还得从Alpha AXP处理器说起

在Alpha AXP处理器上,没有一条指令对应”加载一个32位的证书”这样的操作,取而代之地,实际上是加载两个16位的整数然后将它们合并成32位的。

所以,如果内存分配粒度小于64K,则一个需要重新定位的DLL将会需要对每一次重新分配的地址做出两次调整:一次是高16位地址,另一次是低16位地址。如果这改变了两半地址之间的进位或借位,情况就会变得更糟。(例如,将4K的数据从0x1234F000移到0x12350000,这将迫使地址的低16位和高15位都发生改变。即使移动的地址量远小于64K,但由于存在进位,这项操作仍然对地址的高16位部分产生影响)

除了这个,还有更糟的

Alpha AXP处理器实际上会合并两个16位的带符号整数到一个32位的整数。例如,为了加载0x1234ABCD,你需要首先使用LDAH指令加载0x1234到目标寄存器的高16位,然后再使用LDA指令加上带符号整数-0x5433(因为,0x5433 = 0x10000 – 0xABCD),才能得到预期的结果0x1234ABCD。

因此,如果重定位导致地址在64K块的”下半部分”和”上半部分”之间移动,则必须进行其他修正,以确保正确调整了地址上半部分的算法。由于编译器喜欢对指令进行重新排序,因此该LDAH指令可能距离很远,因此下半部分的重定位记录将不得不采用某种方式来找到匹配的上半部分。

而且,编译器很聪明,如果需要为同一64K区域中的两个变量计算地址,则它们之间共享LDAH指令。如果可以通过不是64K的倍数的值进行重定位,则编译器将不再能够执行此优化,因为在重定位之后,这两个变量不再属于同一64K内存块中。

强制以64K粒度分配内存可解决所有这些问题。

如果你仔细观察的话,你会发现这也解释了为什么2GB边界附近有64K的”无人区”。考虑一下计算值0x7FFFABCD的方法:由于低16位在64K范围内,该值需要通过减法而不是加法来计算。一种比较想当然的解决方案:

上面的做法行不通

Alpha AXP是64位处理器,0x8000不适合放入到16位带符号整数中,因此必须使用-0x8000(负数)。所以,实际发生的是:

你需要添加第三条指令来清除高32位。一种巧妙的技巧是,将零加起来,然后告诉处理器将结果视为32位整数并将其符号扩展为64位。

为什么内存空间分配总是以64K为边界?

如果允许访问2GB边界的64K范围内的地址,则每一次内存地址计算都必须插入上面所提到的第三条ADDL指令,以防万一该地址被重新分配到2GB边界附近的“危险区域”。

要访问地址空间中的最后一个64K区域,会付出一笔非常高的代价:对于所有地址计算,其性能都会受到50%的影响,以避免在实践中永远不会发生这种情况。因此,将这片区域设置为永久禁用,是一种更为明智的选择。

为什么内存空间分配总是以64K为边界?

相关内容

热门资讯

小学语文新课程标准学习心得体... 小学语文新课程标准学习心得体会小学语文新课程标准学习心得体会每次读小学语文课程标准的感受都不同:感受...
观看电影《吴仁宝》的心得体会 观看电影《吴仁宝》的心得体会范文(精选7篇)  当我们受到启发,对学习和工作生活有了新的看法时,写心...
新时代教师的十项准则心得体会 新时代教师的十项准则心得体会(精选15篇)  我们在一些事情上受到启发后,应该马上记录下来,写一篇心...
建团100周年团史的心得体会 建团100周年团史的心得体会  建团100周年团史的心得体会(精选16篇)  我们得到了一些心得体会...
案件防控心得体会 案件防控心得体会范文(通用8篇)  我们在一些事情上受到启发后,心得体会是很好的记录方式,这样就可以...
高效课堂教学反思 高效课堂教学反思(通用7篇)  身为一名刚到岗的人民教师,课堂教学是我们的任务之一,教学的心得体会可...
小学语文国培心得体会 小学语文国培心得体会小学语文国培心得体会第一篇:小学语文国培心得体会20XX年11月18日,我参加了...
暑假社会实践心得体会 精选暑假社会实践心得体会集锦6篇暑假社会实践心得体会 篇1  暑假一转眼就过去了,在这短短的一个多月...
节约粮食心得体会 节约粮食心得体会(精选36篇)  在平日里,心中难免会有一些新的想法,马上将其记录下来,通过写心得体...