内存库矢量处理器中内存访问冲突的条件
Condition for memory access conflict in memory-banked vector processors
Hennessy-Patterson 关于计算机体系结构的书(定量方法第 5 版)说,在具有多个存储体的向量体系结构中,如果满足以下条件(第 5 版第 279 页),则可能会发生存储体冲突:
(bank数量) / LeastCommonMultiple(Number of banks, Stride) < Bank繁忙时间
不过我觉得应该是GreatestCommonFactor而不是LCM,因为如果你的有效bank数小于忙时就会发生内存冲突。我所说的有效银行数量是指这个——假设你有 8 个银行,步幅为 2。那么实际上你有 4 个银行,因为内存访问只会在四个银行排队(例如,假设你的访问都是偶数,从 0 开始,那么你的访问将在银行 0,2,4,6 排队。
事实上,对于正下方给出的示例,此公式甚至不成立。 假设我们有8个内存块,忙时间为6个时钟周期,总内存延迟为12个时钟周期,完成一个步幅为1的64元素向量加载需要多长时间? - 这里他们将时间计算为 12+64=76 个时钟周期。但是,根据给定的条件,内存库会发生冲突,所以我们显然不能每个周期访问一次(等式中的64)。
我是不是理解错了,或者是错误的公式在本书的 5 个版本中幸存下来(不太可能)?
GCD(banks, stride) 应该加入其中;你的论点是正确的。
让我们尝试几个不同的步骤,看看我们得到了什么,
对于银行数量 = b = 8
.
# generated with the calc(1) function
define f(s) { print s, " | ", lcm(s,8), " | ", gcd(s,8), " | ", 8/lcm(s,8), " | ", 8/gcd(s,8) }`
stride | LCM(s,b) | GCF(s,b) | b/LCM(s,b) | b/GCF(s,b)
1 | 8 | 1 | 1 | 8 # 8 < 6 = false: no conflict
2 | 8 | 2 | 1 | 4 # 4 < 6 = true: conflict
3 | 24 | 1 | ~0.333 | 8 # 8 < 6 = false: no conflict
4 | 8 | 4 | 1 | 2 # 2 < 6 = true: conflict
5 | 40 | 1 | 0.2 | 8
6 | 24 | 2 | ~0.333 | 4
7 | 56 | 1 | ~0.143 | 8
8 | 8 | 8 | 1 | 1
9 | 72 | 1 | ~0.111 | 8
x >=8 2^0..3 <=1 1 2 4 or 8
b/LCM(s,b) 总是<=1,所以它总是预测冲突。
我认为 GCF(又名 GCD)看起来适合我目前所看到的步幅值。如果步幅没有将访问权限分配给所有银行,你只会遇到问题,这就是 b/GCF(s,b) 告诉你的。
Stride = 8 应该是最坏的情况,每次都使用同一个bank。 gcd(8,8) = lcm(8,8) = 8。所以两个表达式都给出 8/8 = 1,小于银行 busy/recovery 时间,从而正确预测冲突。
Stride=1当然是最好的情况(如果有足够的bank可以隐藏繁忙的时间就不会冲突)。 gcd(8,1) = 1 正确预测没有冲突:(8/1 = 8,不小于 6)。 lcm(8,1) = 8。(8/8 < 6
为真)错误地预测了冲突。
Hennessy-Patterson 关于计算机体系结构的书(定量方法第 5 版)说,在具有多个存储体的向量体系结构中,如果满足以下条件(第 5 版第 279 页),则可能会发生存储体冲突:
(bank数量) / LeastCommonMultiple(Number of banks, Stride) < Bank繁忙时间
不过我觉得应该是GreatestCommonFactor而不是LCM,因为如果你的有效bank数小于忙时就会发生内存冲突。我所说的有效银行数量是指这个——假设你有 8 个银行,步幅为 2。那么实际上你有 4 个银行,因为内存访问只会在四个银行排队(例如,假设你的访问都是偶数,从 0 开始,那么你的访问将在银行 0,2,4,6 排队。
事实上,对于正下方给出的示例,此公式甚至不成立。 假设我们有8个内存块,忙时间为6个时钟周期,总内存延迟为12个时钟周期,完成一个步幅为1的64元素向量加载需要多长时间? - 这里他们将时间计算为 12+64=76 个时钟周期。但是,根据给定的条件,内存库会发生冲突,所以我们显然不能每个周期访问一次(等式中的64)。
我是不是理解错了,或者是错误的公式在本书的 5 个版本中幸存下来(不太可能)?
GCD(banks, stride) 应该加入其中;你的论点是正确的。
让我们尝试几个不同的步骤,看看我们得到了什么,
对于银行数量 = b = 8
.
# generated with the calc(1) function
define f(s) { print s, " | ", lcm(s,8), " | ", gcd(s,8), " | ", 8/lcm(s,8), " | ", 8/gcd(s,8) }`
stride | LCM(s,b) | GCF(s,b) | b/LCM(s,b) | b/GCF(s,b)
1 | 8 | 1 | 1 | 8 # 8 < 6 = false: no conflict
2 | 8 | 2 | 1 | 4 # 4 < 6 = true: conflict
3 | 24 | 1 | ~0.333 | 8 # 8 < 6 = false: no conflict
4 | 8 | 4 | 1 | 2 # 2 < 6 = true: conflict
5 | 40 | 1 | 0.2 | 8
6 | 24 | 2 | ~0.333 | 4
7 | 56 | 1 | ~0.143 | 8
8 | 8 | 8 | 1 | 1
9 | 72 | 1 | ~0.111 | 8
x >=8 2^0..3 <=1 1 2 4 or 8
b/LCM(s,b) 总是<=1,所以它总是预测冲突。
我认为 GCF(又名 GCD)看起来适合我目前所看到的步幅值。如果步幅没有将访问权限分配给所有银行,你只会遇到问题,这就是 b/GCF(s,b) 告诉你的。
Stride = 8 应该是最坏的情况,每次都使用同一个bank。 gcd(8,8) = lcm(8,8) = 8。所以两个表达式都给出 8/8 = 1,小于银行 busy/recovery 时间,从而正确预测冲突。
Stride=1当然是最好的情况(如果有足够的bank可以隐藏繁忙的时间就不会冲突)。 gcd(8,1) = 1 正确预测没有冲突:(8/1 = 8,不小于 6)。 lcm(8,1) = 8。(8/8 < 6
为真)错误地预测了冲突。