Cache-oblivious algorithm

реклама
 Представим, что перед нами стоит задача
перемножить две матрицы A и B размера n×n.
 Как можно это осуществить?
Применим алгоритм, действующий прямо
по определению (назовем его “Iterative”).
for i <- 1 to n
do for j<- 1 to n
do cij <-0
for k<-1 to n
do cij<-cij + aikbk j
Ci,j = ∑ aikbk j
Время его выполнения на реальной машине: 140 c (N = 210)





Тестирование происходило на системе:
Intel Core i5 2.27Ghz
4096 Mb
L1 32 Kb x2 64 B
L2 256 Kb x2 64 B
Windows 7
Разобьём каждую матрицу на (n/s)*(n/s) подматриц Мij размером s×s
Следующий алгоритм использует эту стратегию(“Block-Mult”):
for i<-1 to n/s
do for j<-1 to n/s
do for k<-1 to n/s
do Ord-Mult(Aik, Bkj, Cij, s)
 ORD-MULT (A, B, C, s) – функция, которая присваивает C = C + AB.
Использует итеративный алгоритм, описанный ранее.
 Изменение времени работы алгоритма от параметра s:
t, sec
160
150
140
130
Block-Mult
120
110
100
90
2
4
8
16
32
64
128
256
512
S
t, sec
160
150
140
130
Block-Mult
Iterative
120
110
100
90
2
4
8
16
32
64
128
256
512
S
Для умножения можно воспользоваться следующим
алгоритмом (обозначим его за “Mult(A)”):
Для умножения матрицы A размером m×n на матрицу размером n×p
рассматривается три случая:
 m >= max{n, p} AB = ( A1 )B = ( A1B )
A2
 n> = max{m,p} AB = (A 1
A2B
B1
A 2)( ) = A 1 B 1 + A 2B2
B2
 p> = max{m,n} AB = A(B 1 B 2) = (AB 1 AB 2)
 Это продолжается пока m = n = p = 1.
 Время его работы можно увидеть на графике:
t, sec
160
150
140
130
Block-Mult
Iterative
Mult(A)
120
110
100
90
2
4
8
16
32
64
128
256
512
S
 Исследователи из MIT 1994
 Чарльз Лейзерсон 1997
 Гаральд Прокоп 1999
 (Z, L) – идеальная модель кэша(“ideal-cache model”)(она будет
использоваться для оценки сложности кэша (“cache complexity”))
 Кэш-линии(“cache lines”)
 Высокий кэш(“tall cache”) (Z = Ω(L2))
 Попадание в кэш (“cache hit”)
 Промах кэша (“cache miss”)
 W(n) - рабочая сложность (“work complexity”)
 Q(n, Z, L) - кэш сложность (“cache complexity”).
 Кэш зависимый (“cash aware”)
 Кэш-независимый (“cache oblivious”)
 Будут ли кэш-независимые алгоритмы, разработанные в рамках
идеальной модели, работать также эффективно для модели с
политиками LRU и FIFO или другой иерархией кэша?
 (Кэш сложность будет называться нормальной (“regular”), если Q(n; Z,
L) = O(Q(n; 2Z, L)))
 Теорема: Оптимальный кэш-независимый алгоритм с нормальной кэш
сложностью остается оптимальным в двухуровневой модели с
вытесняющими политиками (LRU, FIFO).
 <(Z1, L1), (Z2,L2),…, (Zr,Lr) > - многоуровневая идеальная модель
 Свойство вложенности (“inclusion property”):
Ʉi є [1,…, r-1] значения, хранимые в кэше i, хранятся и в кэше i+1
 W(n), Qi(n; Zi, Li) - кэш сложности для Ʉi є[1,…,r]
 Теорема: Если кэш-независимый алгоритм оптимален в
многоуровневой идеальной модели, то он вызывает оптимальное
количество потерь кэша и на каждом уровне кэша.
 Теорема: Оптимальный кэш независимый алгоритм с нормальной кэш
сложностью вызывает асимптотически оптимальное количество
потерь кэша на каждом уровне кэша с оптимальной вытесняющей
политикой или LRU.
(Доказательство этих теорем можно найти в Harald Prokop. “Cache-Oblivious Algorithms.
Masters thesis”, MIT. 1999.)
 Нужно перемножить две матрицы A и B размера n×n. Будем считать,
что матрицы хранятся в построчном порядке и что n>L(чтобы
упростить анализ).
Построчный
(“row major”)
По столбцам
(“column major”)
“Iterative”:
for i <- 1 to n
do for j<- 1 to n
do cij <-0
for k<-1 to n
do cij<-cij + aikbk j
Временная сложность - O(n³)
Количество промахов кэша - Ω(n3/L)
“Block-Mult”:
for i<-1 to n/s
do for j<-1 to n/s
do for k<-1 to n/s
do Ord-Mult(Aik, Bkj, Cij, s)
 ORD-MULT (A, B, C, s) – функция, которая присваивает C = C + AB.
Использует итеративный алгоритм, описанный ранее(O(s3)).
 ϴ(n + n^2/L + n^3/(L*Z^(1/2)))
“Mult(A)”:
Для умножения матрицы A размером m×n на матрицу размером n×p
рассматривается три случая:
A1
A1B
 m >= max{n, p} AB = ( A2 )B = ( A2B )
B1
 n> = max{m,p} AB = (A 1 A 2)( B2 ) = A 1 B 1 + A 2B2
 p> = max{m,n} AB = A(B 1 B 2) = (AB 1 AB 2)
 Это продолжается пока m = n = p = 1.
 ϴ(mnp), ϴ(m + n + p + (mn + np + mp)/L + mnp/L(Z1/2))
1. Самый быстрый с точки зрения асимптотической
сложности алгоритм имеет не больше Ω(lg Z)
промахов кэша, чем асимптотически самый
быстрый кэш зависимый алгоритм.
2. Если существует класс оптимальных кэш зависимых
алгоритмов, решающих определённую задачу, то
существует кэш-независимый алгоритм, решающий
ту же задачу.
 Нужно транспонировать квадратную A матрицу размера N×N.
 Применим алгоритм, действующий прямо по определению (назовем его
“Iterative”).
for (i = 0; i < N; i++)
{
for (j = i+1; j < N; j++)
{
tmp = A[i][j];
A[i][j] = A[j][i];
A[j][i] = tmp;
}
}
Рассмотрим время его выполнения на реальной машине:






Тестирование происходило на системе:
UltraSPARC-II 300 MHz
512 мб
L1 32 б 16 кб
L2 64 б 2 мб
SunOS 5.6
SUN’s Workshop 4.2.
 Время работы от размера от изменения входных данных можно увидеть на графике:
t, sec
14
12
10
8
Iterative
6
4
2
0
10
11
12
13
N
 Если учесть затраты на ввод и вывод данных между





кэшем и основной памятью, то можно в несколько раз
уменьшить время работы алгоритма.
Z - размер всего кэша
L - длина линий кэша
Aʳ΄ˢ = { ai,j | rL <= i < (r+1)L, sL <= j < (s+1)L, 0 <= r,s <
N/B-1, r,s є NU{0} }.
C = Aᵀ, где Cˢ΄ʳ = (Aʳ΄ˢ)ᵀ.
“Block-Transpose”
Пример его применения:
L=2
1
2
3
4
1
2
3
4
5
6
7
8
5
6
7
8
9
10
11
12
9
10
11
12
13
14
15
16
13
14
15
16
1
5
9
13
2
6
10
14
3
7
11
15
4
8
12
16
3
7
4
8
 Время его работы можно увидеть на графике:
t, sec
14
12
10
8
Iterative
Block-Transpose
6
4
2
0
10
11
12
13
N
Для транспонирования можно воспользоваться следующим
алгоритмом (обозначим его за “Transpose(A)”):
Вход: Матрица A размера m×n
Выход: Матрица B размера n×m
Если n>=m A = (A1 A2) B = ( B1 )
B2
A1
Если n<m A = ( A2 ) B = ( B1 B2 )
B1 = Transpose(A1), B2 = Transpose(A2)
 Время его работы можно увидеть на графике:
t, sec
14
12
10
Iterative
8
Block-Transpose
Transpose(A)
6
4
2
0
10
11
12
13
N
 Изменим размер линий кэша (L = 27)
t, sec
14
12
10
Iterative
8
Block-Transpose
Transpose(A)
6
4
2
0
10
11
12
13
N
 Изменим размер линий кэша (L = 26)
t, sec
14
12
10
Iterative
Block-Transpose
8
Transpose(A)
Iterative(2)
Block-Transpose(2)
6
Transpose(A)(2)
4
2
0
10
11
12
13
N
 Изменим размер линий кэша (L = 25)
t, sec
14
12
Iterative
10
Block-Transpose
Transpose(A)
Iterative(2)
8
Block-Transpose(2)
Transpose(A)(2)
Iterative(3)
6
Block-Transpose(3)
Transpose(A)(3)
4
2
0
10
11
12
13
N
Гареев Роман КН - 301, 2011 год
Скачать