跳转到主要内容

G.3 深入探讨向量存储系统

要维持每时钟周期取出或存入一个字的启动速率,存储系统就必须能够以这一速率提供或接收数据。正如第 4 章所述,通常的做法是将访问分散到多个独立存储体。大量存储体有助于处理按行或按列访问数据的向量加载、存储。

所需访问速率与存储体访问时间,决定了需要多少个存储体才能避免停顿。下面的例子说明这些时序在向量处理器中如何配合。

例题 假设从字节地址 136 开始读取一个含 64 个元素的向量,一次存储器访问耗时 6 个时钟周期。要支持每周期读取一个元素,需要多少个存储体?各存储体收到哪些地址?不同元素何时到达 CPU?

解答 每次访问耗时 6 个周期,因此至少需要 6 个存储体;不过,我们希望存储体数为 2 的幂,故选择 8 个。图 G.7 给出一个具有 8 个存储体、访问延迟为 6 个时钟周期的系统中,最初几组访问的时序。

周期编号存储体 0存储体 1存储体 2存储体 3存储体 4存储体 5存储体 6存储体 7
0136
1忙144
2忙忙152
3忙忙忙160
4忙忙忙忙168
5忙忙忙忙忙176
6忙忙忙忙忙184
7192忙忙忙忙忙
8忙200忙忙忙忙
9忙忙208忙忙忙
10忙忙忙216忙忙
11忙忙忙忙224忙
12忙忙忙忙忙232
13忙忙忙忙忙240
14忙忙忙忙忙248
15256忙忙忙忙忙
16忙264忙忙忙忙
图 G.7 按存储体编号和访问开始时隙列出的存储器字节地址。每个存储体在访问开始时锁存元素地址,随后忙碌 6 个时钟周期,再把值返回 CPU。CPU 每周期只能提供一个新地址、接收一个数据项,因此无法使全部 8 个存储体始终忙碌。

真实存储体的时序通常分为访问延迟和存储体周期时间(也称存储体忙时)两个部分。访问延迟,是地址到达存储体之后,直到存储体返回数据值的时间;忙时则是存储体被一个请求占用的时间。访问延迟会增加从存储器读取向量的启动开销。总存储器延迟还包括地址和数据在 CPU 与存储体之间穿过流水化互连网络的时间。存储体忙时决定存储系统的有效带宽,因为在该忙时结束之前,处理器不能向同一存储体发出第二个请求。

前例使用的简单非流水化 SRAM 存储体,访问延迟与忙时大致相同。对于流水化 SRAM 存储体,访问延迟大于忙时,因为每个元素的访问只占用存储体流水线的一个阶段。对于 DRAM 存储体,访问延迟通常短于忙时,因为 DRAM 在破坏性读取后,需要额外时间恢复读出的值。对于支持同时进行多次向量访问,或允许向量加载、存储采用非顺序访问的存储系统,存储体数应大于最低要求,否则就会发生存储体冲突。

如果步长与存储体数互质,并且存储体数量足以避免单位步长访问发生冲突,那么单条向量访存指令内部就不会发生存储体冲突。

在没有存储体冲突时,多字步长与单位步长的访问速率相同。如果存储体数超过避免步长为 1 时发生停顿所需的最低数量,就能降低某些其他步长下的停顿频率。例如,64 个存储体配合步长 32 时,每隔一次访问才停顿一次,而非每次访问都停顿。若原来步长为 8、存储体数为 16,则每隔一次访问停顿一次;改用 64 个存储体后,步长 8 每八次访问才停顿一次。多个存储器流水线和/或多个处理器共享同一存储系统时,也需要更多存储体来避免冲突。即使只有一条存储器流水线,前一条指令的最后几个元素与后一条指令的最初几个元素之间,也可能在单位步长访问中发生存储体冲突;增加存储体数可以降低此类指令间冲突的概率。2011 年,大多数向量超级计算机已将每个 CPU 的访问分散到数百个存储体。非单位步长访问仍可能出现存储体冲突,因此程序员通常尽量选择单位步长访问。

译注: 上段给出的停顿频率还取决于存储体忙时,原文没有为这些步长示例另行说明忙时条件。例如,若继续采用前例的 6 周期忙时,64 个存储体、步长 8 会循环访问 8 个不同存储体,单条连续访存序列不必每八次停顿一次。

现代超级计算机可能有数十个 CPU,每个 CPU 又有多条存储器流水线,连接到数千个存储体。为每一条流水线与每一个存储体分别提供专用通路并不现实,因此通常采用多级交换网络将两者连接起来。当不同向量访问争用同一网络通路时,交换网络可能发生拥塞,使存储系统出现额外停顿。

表格阅读