坚果手机|关于x86平台上内存对齐的重要性
【坚果手机|关于x86平台上内存对齐的重要性】
有时候 , 未对齐的内存访问 , 可能会导致系统挂起 。
有一些显卡不允许驱动程序一次性就访问所有的显卡内存 。 取而代之的做法是:它给你一个访问窗口 , 你可以从中选择一个显存的子集来进行访问 。 举个例子 , EGA显卡有256K的字节空间 , 它们被划分到4个64K的存储单元中 。 如果你希望访问第一个64K , 则你需要将这个64K空间(bank 0)选择到访问窗口中 , 同样的道理 , 如果你需要访问第二个64K , 则你需要将它(bank 1)选择到访问窗口中 。
基于存储单元的访问机制 , 使得内存访问变得复杂起来 , 举个例子 , 如果你希望拷贝一块内存数据到一个存储单元中 , 你需要首先检查这个目标内存空间是否跨越了存储单元的边界 , 并将数据拆分成片段进行拷贝动作 。
如果你正在执行的操作需要一段连续性内存访问(例如 , 在屏幕上绘制一条对角线) , 则你还需要判断这条线是否会跨越存储单元的界限 。
为了简化这一操作 , Windows 95引入了一个名为”VFLATD”的驱动 , 可以用来将单元式访问抽象化为平坦式内存访问 。 这一转换机制对于DirectDraw也十分重要 , 特别是IDirectDrawSurface::Lock方法可以提供对平坦的显卡内存进行直接访问 。 举个例子 , 如果应用程序想观测到256K的表面(surface)并访问其中第一个64K的空间 , VFLATD驱动就会将第一个64K选择到访问窗口提供访问接口 。
这种设计对于那些遵循了内存对齐的代码很奏效 , 但是如果你访问了未对齐的内存 , 则这会导致VFLATD驱动进入一段无限循环 , 并最终导致机器挂起 。
假设你进行跨越两个存储单元的未对齐内存访问 。 这种内存访问永远无法满足 。 在未对齐访问的较低部分发生页面错误(Page Fault) , VFLATD将较低的存储体映射到内存中 。 然后在未对齐访问的较高部分发生页面错误 , VFLATD现在必须映射较高的存储空间 , 这将取消映射较低的存储单元 , 因为显卡是基于存储单元进行切换的 , 一次只能映射一个单元 。 现在在内存下部发生页面错误 , 并且会一直无限循环 。
这个故事的寓意:请保持内存访问对齐 , 即使在x86平台上也是如此 , 大多数人会认为违反对齐规则是安全的 。 这可不大对 。
最后Raymond Chen的《The Old New Thing》是我非常喜欢的博客之一 , 里面有很多关于Windows的小知识 , 对于广大Windows平台开发者来说 , 确实十分有帮助 。
本文来自:《Importance of alignment even on x86 machines》
- iPhone|Plus时隔5年回归!曝苹果全新6.7寸手机名为iPhone 14 Plus
- 红米手机|真我GTNeo3和红米K50谁的综合实力更好,哪个更值得购买?
- 图像传感器|到手1849元重量189g这才是高性价比的骁龙870直屏手机
- ios16|一步到位能用5年,目前这3款手机能闭眼入,买手机不要太小气
- 酷派|OPPO折叠屏手机专利曝光酷派新机cool 12A上架
- 一加科技|618手机黑马清单:小米这次直接杀疯了
- 红米手机|红米两款新机曝光,Note12系列和K50 Ultra已安排,拍照大幅提升
- 苹果|618市场怎么样?手机市场销量排行一边倒?这又说明了什么?
- harmonyos|两年前的小米10 Pro,放到现在相当于什么价位的手机?
- 红米手机|红米K60Pro大变样:5450mAh大电池+98%屏占比,屏幕旗舰来临
