Умножение матрицы на вектор
Задача умножения двух квадратных матриц (n x
n)
Последовательный код программы умножения двух квадратных матриц
(n x n) на языке C:
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
c[i][j]=0;
for(k=0;k<n;k++)
{
c[i][j]=c[i][j]+a[i][j]*b[i][j];
}}}
Этот алгоритм требует
выполнения n3 операций умножения и
n3 операций сложения, ведущих к оценке общего времени
(time complexity) как O(n3).
Рассмотрим различные
алгоритмы распараллеливания этой задачи и сравним их производительность. Этим
будет наглядно показано, что процесс распараллеливания является процессом
творческим.
1)Простой параллельный код
Для
n- процессоров получим общее время (time complexity) как
O(n2). (Каждый процессор выполняет цикл операций для
своего фиксированного i)
Для n2-
процессоров получим общее время (time complexity) как O(n), где один
элемент матриц A и B передается каждому процессору.
(Каждый процессор выполняет цикл операций для своей пары фиксированных
i и j)
В обоих случаях с n- и
n2- процессорами время исполнения программы можно оценить
как O(n3)=n*O(n2)=n2,*O(n).
Результат достаточно неожиданный на первый взгляд. Это не оптимальные алгоритмы
распараллеливания (так как O(n3) не равно
n3*O(log n).
2)Блочное матричное
умножение
Алгоритм распараллеливания умножения двух квадратных
матриц (n x n) с использованием подматриц
Представим нашу матрицу
в виде s2 подматриц. Каждая подматрица будет состоять из
(n/l) x (n/l) элементов. Обозначим Ap,q
подматрицу в подматрице ряда p и подматрице столбца q.
Поясняющие рисунки :
for(p=0;p<s;p++)
{
for(q=0;q<s;q++)
{
C_p,q=0;
for(r=0;r<m;r++)
{
C_p,q=C_p,q+A_p,r*B_r,q;
}}}
Строка программы "C_p,q=C_p,q+A_p,r*B_r,q" означает умножение
подматриц Ap,r и Br,q и дальнейшее
сложение их в подматрицу Cp,q.
Для того, чтобы один
процессор вычислял каждый из элементов C, понадобится
n2 процессоров. Необходим один ряд элементов A
и один столбец элементов B. Некоторые одни и те же элементы
посылаются на несколько процессоров. Можно использовать подматрицы.
На
следующем рисунке изображена работа Pi,j процессора.
Анализ
затраченного времени
a) На обмен сообщениями:
При разделении сообщений
на n2 процессоров время, затраченное на коммуникации:
tcomm=n2
(tstartup+2n*tdata)+n2(tstartup+
2n*tdata)=n2(2tstartup+(2n+1)tdata)
Широкое вещание по отдельной связи даст:
tcomm=(tstartup+(n2)
tdata)+ n2(tstartup+(n2)
tdata).
б) На вычисления:
Вычисление каждого элемента
состоит из m умножений и n сложений:
tcomm=2n
n чисел могут быть сложены за
log n шагов, используя n-штук процессоров:
Общее время (time
complexity) при использовании n3 процессоров оценивается
как O(log n).
[Назад] [Оглавление] [Вперед]
Последнее обновление 21.11.2001 WebMaster