一个相关的问题及其答案是here.另一个来源是here.但他们都没有解决我的问题.
假设CPU的访问粒度为4个字节.这意味着CPU一次读取4个字节.我上面列出的材料都说如果我访问未对齐的数据,比如地址0x1,那么CPU必须进行2次访问(一次来自地址0x0,0x1,0x2和0x3,一次来自地址0x4,0x5,0x6和0x7)并结合结果.我不明白为什么.当我发出访问地址0x1时,为什么CPU不能从0x1,0x2,0x3,0x4读取数据.它不会降低性能并导致电路复杂化.
先感谢您!
It will not degrade the performance and incur much complexity in circuitry.
这是我们认为错误的假设,因为它真的会让人进一步理解.
Your comment在另一个问题中使用了更为恰当的措辞(“我认为它不会降低”……)
您是否认为内存架构并行使用多个内存芯片以最大化带宽?并且特定数据项只在一个芯片中,您不能只读取最方便的芯片并期望它拥有您想要的数据.
现在,CPU和存储器可以连接在一起,使得0-7位仅连接到芯片0,8-15连接到芯片1,16-23连接到芯片2,24-31连接到芯片3.并且对于所有整数N存储单元4N存储在芯片0,芯片1中的4N 1等中.并且它们是每个芯片中的第N个字节.
让我们看看存储在每个存储芯片的每个偏移处的存储器地址
memory chip 0 1 2 3 offset 0 0 1 2 3 1 4 5 6 7 2 8 9 10 11 N 4N 4N+1 4N+2 4N+3
因此,如果从内存字节0-3,N = 0加载,每个芯片报告其内部字节0,这些位都会在正确的位置结束,并且一切都很好.
现在,如果您尝试从内存位置1开始加载一个单词,会发生什么?
首先,我们看看它的完成方式.第一个存储器字节1-3,存储在偏移0的存储器芯片1-3中,最终位于第8-31位,因为即使您要求它们位于0-23位,这也是这些存储器芯片所连接的位置.这不是什么大问题,因为CPU可以使用与逻辑左移相同的电路在内部调动它们.然后在下一个事务存储器字节4(存储在偏移1的存储器芯片0中)被读入0-7位并且被调到第24-31位,你想要它.
注意一下这里.你要求的字是在偏移量之间分开的,第一个存储器事务从三个芯片的偏移量0读取,第二个存储器事务从另一个芯片的偏移量1读取.这就是问题所在.你必须告诉存储器芯片偏移量,这样它们才能发回正确的数据,偏移量大约为40位,信号速度非常快.现在只有一组偏移信号连接到所有存储器芯片,为了进行未对齐存储器访问的单个事务,您需要运行到每个存储器芯片的独立偏移(称为地址总线BTW).对于64位处理器,您将从一个地址总线更改为八个,增加近300个引脚.在CPU使用700到1300个引脚的世界中,这几乎不能称为“电路没有太多增加”.更不用说来自许多额外高速信号的噪声和串扰的巨大增加.
好吧,它并不是那么糟糕,因为地址总线上一次最多只能有两个不同的偏移量,一个总是另一个加一个.因此,您可以通过一条额外的线路到达每个存储器芯片,实际上说(读取地址总线上列出的偏移量)或(读取下面的偏移量)这是两种状态.但现在每个内存芯片中都有一个额外的加法器,这意味着它必须在实际进行内存访问之前计算偏移量,这会降低内存的最大时钟速率.这意味着如果您希望未对齐访问更快,则对齐访问会变慢.由于99.99%的访问权限可以对齐,因此这是净损失.
这就是为什么未对齐访问分为两个步骤的原因.因为地址总线由所涉及的所有字节共享.这实际上是一种简化,因为当你有不同的偏移时,你也有不同的缓存行,所以所有缓存一致性逻辑必须加倍才能处理CPU内核之间通信的两倍.