在VLIW中增加一倍的指令量是否允许处理器实现双倍的性能,因为它可以并行执行两倍多的操作?
发布于 2022-08-10 11:27:30
答案取决于计算的类型。让我们说,我们的机器上只有一个ALU。假设我们有计算数组和的代码:
for(int i = 0; i < len; i++)
{
sum += arr[i]
}伪程序集将如下所示:
; tick 0:
LD arr[i] -> %r0 ; load value from memory to register on ALU0
; tick 1:
ADD sum, %r0 -> sum ; increment sum value on ALU0循环体需要两条滴答。如果我们加倍ALU号并展开循环体,我们将得到以下情况:
; tick 0:
LD arr[i] -> %r0 ; load value from memory to register on ALU0
LD arr[i+1] -> %r1 ; load value from memory to register on ALU1
; tick 1:
ADD sum, %r0 -> sum ; increment sum value on ALU0
; tick 2:
ADD sum, %r1 -> sum ; increment sum value on ALU0现在我们可以看到,循环体需要3个滴答。可以进行并行加载,但计算本身不能并行,因为计算结果依赖于先前的循环迭代。因此,我们不会将ALU的数量增加一倍。
现在让我们看另一个例子-两个向量之和:
for(int i = 0; i < len; i++)
{
c[i] = a[i] + b[i]
}让我们来看一个伪程序集:
; tick 0:
LD a[i] -> %r0 ; load value a[i] on ALU0
; tick 1:
LD b[i] -> %r1 ; load value b[i] on ALU0
; tick 2:
ADD %r0, %r1 -> %r2 ; add values on ALU0
; tick 3:
ST c[i] <- %r2 ; store value to c[i] on ALU0我们数四下身体。如果我们把ALU的数量增加一倍会发生什么?在这种情况下,我们不依赖于以前的计算。因此,我们可以展开循环的主体,并有以下代码:
; tick 0:
LD a[i] -> %r0 ; load value a[i] on ALU0
LD b[i] -> %r1 ; load value b[i] on ALU1
; tick 1:
LD a[i] -> %r0 ; load value a[i] on ALU0
LD b[i] -> %r1 ; load value b[i] on ALU1
; tick 2:
ADD %r0, %r1 -> %r2 ; add values on ALU0
ADD %r0, %r1 -> %r2 ; add values on ALU1
; tick 3:
ST c[i] <- %r2 ; store value to c[i] on ALU0
ST c[i] <- %r2 ; store value to c[i] on ALU1我们仍然有4个滴答,但在这4个滴答中,我们计算了2个循环迭代。所以我们可以说,把ALU数量增加一倍,我们的表现就会提高一倍。
这些简单的例子只说明了指令级并行性取决于特定算法的思想,而仅将ALU加倍可能会导致性能加倍。
在更复杂的情况下,VLIW系统必须实现复杂的优化编译器,这种编译器可以进行非VLIW系统在硬件中实现的优化。在某些情况下,它在某些-更坏的情况下更有效。
https://stackoverflow.com/questions/63982582
复制相似问题