1
Лекция 7
Умножение матрицы на вектор
Рассмотрим алгоритмы умножения матрицы на вектор. Пусть имеется матрица A размером m на n, где m - число строк, а n – число столбцов, и пусть имеется вектор X длины n, тогда в результате умножения матрицы на вектор получим вектор Y длиной m, элементами которого будут суммы произведений элементов строк матрицы на соответствующие элементы вектора. Для примера рассмотрим такое произведение малой размерности:
a11 a12 |
|
× |
x |
|
a11 x1 +a12 x2 |
|
||||
AX = a a |
|
|
1 |
|
= a x |
+a x |
. |
|||
|
21 22 |
|
|
x2 |
|
12 1 |
22 2 |
|
||
|
|
|
|
|
|
|
|
|||
|
|
|
|
|
|
+a32 x2 |
||||
a31 a32 |
|
|
|
|
|
a31 x1 |
|
Обозначим через ai - вектор-строку матрицы А, т.е. a1 =[a11, a12 ]; a2 =[a21, a22 ] , тогда
(a1, X )
AX = (a2 , X ) , (1)(a3 , X )
n
где (ai , X ) = ∑aij x j - скалярное произведение векторов.
j =1
Таким образом, вычисление АX сводится к вычислению m скалярных произведений. С другой стороны, обозначим через αi столбцы матрицы A, то есть:
|
a11 |
|
|
a12 |
|
|
||
α = a |
21 |
; α |
2 |
= a |
22 |
|
, |
|
1 |
|
|
|
|
|
|||
|
|
|
|
|
|
|
|
|
|
a31 |
|
|
a32 |
|
|
тогда произведение можно представить как
a11 |
|
|
a11 |
|
|
n |
|
|
|
x1 |
|
|
x2 |
= ∑αi xi . |
(2) |
AX = a21 |
|
+ a22 |
|
||||
|
|
|
|
|
|
i =1 |
|
a31 |
|
|
a32 |
|
|
|
|
Используя нотацию языка С для формулы (1) алгоритм вычисления можно представить
for(i=0;i<m;i++) |
(1a) |
for(j=0;j<n;j++) |
|
y[i]=y[i]+a[i][j]*x[j]; |
|
Для формулы (2): |
|
for(j=0;j<n;j++) |
(2a) |
for(i=0;i<m;i++) |
|
y[i]=y[i]+a[i][j]*x[j]; |
|
Или в векторном виде согласно формуле (2): for(i=0;i<n;i++)
y=y+αi*xi;
Высокопроизводительные вычислительные системы и параллельное программирование. Кудерметов Р.К.
2
В алгоритме (1a) для каждого i вычисляется скалярное произведение (во внутреннем цикле по j) i-ой строки матрицы A на вектор X.
С точки зрения последовательной машины различия между алгоритмами (1a) и (2a) нет. Реализация на векторных машинах может иметь различие. Оно заключается в следующем.
Если в компьютере аппаратно реализована команда скалярного произведения, то для представления (1) необходимо реализовать m команд скалярного умножения (ai , X ) . Вре-
мя выполнения этой команды на системе с наличием конвейеров оценивается по формуле Tc = S1 + τ1n , следовательно весь алгоритм в идеале может быть выполнен за время
T1 = S1m + τ1nm .
Если в компьютере реализована команда saxpy, то есть аппаратная реализация операции ax+y, то на нем целесообразнее перемножать матрицу на вектор по алгоритму (2а). При этом необходимо выполнить n операций y = y +αi * xi . Тогда время такой операции мож-
но оценить по формуле T2 = S2 n + τ2 nm .
Сравнивая T1 и T2, обратим внимание, что для разных машин значения S и τ могут быть разными. Время так же зависит от размерностей матрицы и вектора.
Эффективность может зависеть и от реализации компилятора: если элементы матрицы А хранятся по столбцам, то выгодна реализация согласно представлению (2), т.к. элементы векторов αi хранятся в последовательных ячейках, а выборка векторов в векторном компью-
тере, как правило, реализована. Для представления (1) элементы векторов αi будут размеще-
ны с шагом m, поэтому время на выборку векторов может оказаться значительным. В случае, если в параллельном компьютере не реализованы операции скалярного произведения и saxpy, то алгоритм может быть таким: вначале векторы αi и Х по-компонентно умножаются,
затем соответствующие результаты складываются. Суммирование можно организовать по методу логарифмического сдваивания, разбив, например, элементы aij x j на две группы по
n/2 элементов.
Подводя итог рассмотрению вычисления произведения матрицы на вектор, выделим факторы, определяющие эффективность его реализации:
1.Зависимость от математического (алгоритмического) представления и от типа компьютера (наличия в нём специальных аппаратно реализованных операций);
2.Зависимость времени выполнения от размерности вектора и матрицы и типа компьютера;
3.Отношение размерностей матрицы и вектора к размерности векторных регистров в компьютере;
4.Способ представления матрицы в памяти компьютера;
5.Зависимость реализации в части загрузки-выгрузки векторов от некоторых конструктивных особенностей векторных машин. В алгоритме (2а) в каждом цикле по i при прямой реализации приходится загружать и записывать из векторного регистра вектор y. Поэтому важно, имеется ли возможность в векторной машине использовать текущее значение y без промежуточной записи вектора в памяти.
6.Следующее, на что нужно обратить внимание, это имеется ли у машины конвейер, позволяющий совместить арифметическую операцию (в данном случае сложение) с выборкой сле-
дующего вектора αi. Если эти возможности реализованы, то следует применить метод развёртывания циклов. То есть представлении алгоритма в виде:
for(i=0;i<m;i+=2) y=y+xi*αi + xi+1*αi+1
Говорят, что в этом случае вектор цикл развёрнут на глубину 2. В этом случае вектор y выгружается в два раза реже. Понятно, при аппаратных возможностях цикл можно развернуть на большую глубину. В источниках упоминаются примеры развертывания циклов на глубину 8.
Высокопроизводительные вычислительные системы и параллельное программирование. Кудерметов Р.К.
3
Обсудим реализацию матрично-векторного умножения на параллельных процессорах. Рассмотрим алгоритм (2а). Если число процессоров p=n и
n
Ax = ∑αi x ,
i=1
где αi - столбцы матрицы А.
Каждое умножение вектора на скаляр можно выполнить на отдельном процессоре. И далее организовать сложение векторов методом логарифмического сдваивания. При этом, если используется локальная память для каждого процессора, то для суммирования методом сдваивания необходимо log n пересылок. Вопрос синхронизации в этом случае решается ес-
тественным образом: пока второй вектор не загружен, процессор ожидает.
Если используется глобальная память, то пересылки не нужны, но для организации суммирования необходим механизм синхронизации, например, с помощью семафоров (флагов). Окончательный результат после суммирования сформируется в одном из процессоров.
Алгоритм скалярных произведений (а1) обладает максимальным параллелизмом, т.к. на каждом из m процессоров можно выполнять независимое скалярное произведение векторов. Суммирование методом сдваивания не нужно. Синхронизация необходима только перед окончательным формированием результирующего вектора, но этот результат, в отличие от (а2), необходимо сформировать.
Если длины векторов больше аппаратных векторов (как правило) или числа процессоров, то алгоритмы необходимо делить на число, кратное их длине, т.е. представить матрицу в виде блоков:
|
A |
|
|
||
|
A1 |
|
|
||
Ax = |
|
2 |
|
x |
|
|
M |
|
|||
|
|
||||
|
|
|
|
|
|
|
Ap |
|
|||
|
|
|
|
|
A1x
=A2Mx .Ap x
Высокопроизводительные вычислительные системы и параллельное программирование. Кудерметов Р.К.