🎰地址对齐→Bank Conflict

type
status
date
slug
summary
tags
category
icon
password

地址对齐

一般编程中,几乎感知不到这个问题,因为相关工作都被编译器完成了,但是如果要编写高性能程序,就必须要对地址对齐有了解。

memory word

cpu一次内存访问的最小单元,一般cpu对内存地址的对齐要求也就是要和memory word的大小对齐。比如memory word为32位,4字节,cpu也就要求地址需要4字节对齐。

没有对齐会怎样?

  1. cpu需要花费两个周期进行内存访问,分别访问前后两个对齐的地址,取出数据并进行拼接
  1. fault

为什么?

程序员眼中的内存是一个字节一个字节的,我可以随心所欲的访问操作。但是cpu眼中的memory并不是,cpu眼中的memory的最小单位就是一个memoy word。
 
notion image
How programmers see memory
notion image
How processors see memory
对于CPU来说,一次内存访问,要么访问这个memory word, 要么访问那个memory word, 是不可拆分。所以如果你想要访问一个起始地址为:0x2,的int32_t类型的数据,cpu在一个周期是做不到,cpu只能先访问0x0 地址开始的4字节,然后访问 0x4 开始的4字节,然后将两次访存的结果拼接起来。

为什么?

经过上面的讲解相信已经能够理解为什么访问非对齐的地址需要两个周期了,可是为什么?为什么cpu 一次访存必须访问一个memory word,不能拆分?

总线

cpu通过总线访问内存,总线的位宽就是其一个周期能传输的数据量,也就是对应的cpu的memory word。这也就解释了cpu一次访存的最小单位是memory word的原因。

为什么?

总线一次访问memory word,可是究竟为什么就不能从对齐的地址开始呢?不能把总线的数据传输的起始地址设为:0x1呢?

内存物理结构

我们看到memory是一整块memory,但实际上为了提高访存带宽,memory是由多个memory 芯片组成的,如下图:
notion image
notion image
假设原本每个芯片一个周期可以读取1个字节的数据,现在使用4个芯片构成memory,这样就可以同时访问4个芯片,一次访存的大小也就提高了4字节。
考虑总线访存,总线每次拿到一个其实offset, 然后在这4个芯片中都去取offset位置的数据,传输到cpu。
假设offset为0, 就是访问上图中第一行的4个字节,对应到程序员眼中就是:0x0开始4个字节
假设offset为1,就是访问上图中第二行的4个字节,对应到程序员眼中就是:0x4开始4个字节
 
于是乎就会发现,不管offset为多少,都不能一次性访问从0x1开始的4个字节,这本质上是由于总线访存时,只有一个offset,每个芯片都用这个offset。 如果总线能为每个芯片都提供一个offset,这样就能实现访问非对齐地址,但是这又会给电路带来更多的复杂性。
 
因此,由于内存结构的特点,想要一次性访问0x1开始的4个字节,在电路上就是不可能的。
 
本小节参考:

思考

对于在某款芯片上,如果要求地址按X对齐,是否暗示了芯片一次访存最小是X字节,并且暗示了memory芯片的物理结果?

Bank Conflict

NPU tensor layout

RoPE 旋转位置编码饮茶与double buffer
Loading...
Catalog