VLIW - Увеличение ширины Instructon

Может ли удвоение количества инструкций в VLIW позволить процессору достичь удвоенной производительности, поскольку он может выполнять в два раза больше операций параллельно?

1 ответ

Ответ зависит от типа вычислений. Допустим, у нас на машине есть только одно АЛУ. Представьте, что у нас есть код, который считает сумму массива:

      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

Тело цикла занимает 2 тика. Если мы удвоим номер 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

Считаем тело за 4 тика. Что произойдет, если мы удвоим количество 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 реализуют на аппаратном уровне. В каких-то случаях работает лучше, в каких-то - хуже.

Другие вопросы по тегам