首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么远指针速度慢?

为什么远指针速度慢?
EN

Stack Overflow用户
提问于 2022-07-28 03:32:37
回答 1查看 84关注 0票数 2

最近为了好玩,我在16位DOS上编写了一些东西。我看到很多人提到,远指针比近指针慢,为了避免它们。

为什么?

从装配的角度来看,这是有意义的。涉及到几项额外的指导。您必须存储段寄存器的旧值,将新段存储到寄存器中,然后将其移到CS或DS中(即时模式存储在8086中不是有效的操作码)。然后,你可以做你需要做的任何事情在这一段。之后,你必须恢复旧的价值。

听起来似乎很多,但实际上,这并没有消耗太多的周期。我想,如果您使用的每个指针都位于不同的段中,这可能会加起来,但是数据通常是分组的。所以,除非你在整个地方弹跳,因为其他原因,这是缓慢的,点球不应该那么糟糕。如果你必须使用DRAM,那应该是成本的主导,对吗?

我觉得这个故事还有很多,我很难找到它。希望有个8086巫师能记得这些东西。

澄清:我感兴趣的是实际的16位处理器,如8086和80286的真实模式。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-07-28 07:30:26

为什么远指针速度慢?

段寄存器负载太复杂,无法将核心的前端转换为微操作。相反,它们被存储在一个小ROM中的微型操作系统“模仿”。这从一些分支开始(它是哪种CPU模式?),通常这些分支无法从CPU的分支预测中获益,从而导致延迟/s。

为了避免段寄存器负载(例如,当多次使用相同的远指针时),软件倾向于使用更多的段寄存器(例如倾向于使用ESFSGS);这在指令中增加了更多的前缀(段覆盖前缀)。这些额外的前缀也可以减慢指令解码速度。

--我猜如果您使用的每个指针都位于不同的段中,这可能会加起来,但是数据通常是分组的。

编译器没那么聪明。如果一小部分代码使用4个far指针,而这些指针恰好都使用相同的段,那么编译器将不知道它们都在同一个段中,并且不管如何,都会执行昂贵的段寄存器加载。要解决这个问题,您可以将数据描述为一个结构(例如,指向具有4个字段而不是4个不同指针的结构的一个指针);但这需要程序员以不同的方式编写软件。

例如,如果您执行类似于“into (Void){ int a;返回栏(&a) }”的操作,那么ss可能会被传递到堆栈上,然后被调用者(bar)会将其加载到另一个段寄存器中,因为bar()必须假定指针可以指向任何位置。

另一个问题是,有时数据大于段(例如,一个不适合64 KiB段的100000字节数组);因此,某个人(程序员或编译器)必须计算和加载不同的段来访问(部分)相同的数据。所有指针算法都可能需要考虑到这一点(例如,看起来微不足道的pointer++;可能会变得更像offset++; segment += (offset >> 4); offset &= 0x000F;,从而导致段寄存器负载)。

,如果你必须使用DRAM,那应该是成本的主导,对吗?

对于真正的模式,您被限制在大约640 KiB的内存中,并且CPU中的缓存通常要大得多,所以您可以预期每个内存访问都会受到高速缓存的影响。在某些情况下(例如,级联湖CPU,每个核心有一个MiB of L2缓存),您甚至不会使用L3缓存(这将是L2的全部命中)。

您还可以预期,段寄存器加载比缓存命中更昂贵。

希望一个8086年的巫师在那些记得这些东西的人身边徘徊。

当人们说“分割很糟糕,应该避免”时,他们并没有想到一个已经过时了40年(8086)的CPU,他们想到的是本世纪相关的CPU。他们中的一些人也可能考虑的不仅仅是性能(尤其是对于汇编语言程序员来说,分段是一个烦人/额外的负担)。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73146953

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档