35
Лекция 2: Оптимизация ветвлений и циклов (Branch prediction and loop optimization) Курносов Михаил Георгиевич к.т .н. доцент Кафедры вычислительных систем Сибирский государственный университет телекоммуникаций и информатики http://www.mkurnosov.net

Оптимизация ветвлений и циклов › teaching › uploads › HPC › hpcs-lecture2.pdf · Лекция 2: Оптимизация ветвлений и циклов

  • Upload
    others

  • View
    17

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Оптимизация ветвлений и циклов › teaching › uploads › HPC › hpcs-lecture2.pdf · Лекция 2: Оптимизация ветвлений и циклов

Лекция 2:

Оптимизация ветвлений и циклов

(Branch prediction and loop optimization)

Курносов Михаил Георгиевич

к.т.н. доцент Кафедры вычислительных систем

Сибирский государственный университет

телекоммуникаций и информатики

http://www.mkurnosov.net

Page 2: Оптимизация ветвлений и циклов › teaching › uploads › HPC › hpcs-lecture2.pdf · Лекция 2: Оптимизация ветвлений и циклов

Вычислительный конвейер (Pipeline)

22

.text

movl %ebx, %eax

cmpl $0x10, %eax

jne not_equal

mov %eax, %ecx

jmp end

not_equal:

mov $-0x1, %ecx

end:

Branch Prediction Unit (BPU)

Step IF ID EX ST

1 movl

2 cmpl movl

3 jne cmpl movl

4 ??? jne cmpl movl

5

6

7

Page 3: Оптимизация ветвлений и циклов › teaching › uploads › HPC › hpcs-lecture2.pdf · Лекция 2: Оптимизация ветвлений и циклов

Модуль предсказания переходов

33

� Модуль предсказания условных переходов

(Branch Prediction Unit, BPU) – компонент процессора,

имеющего конвейерную архитектуру, определяющий

направление ветвлений (будет ли выполнен условный

переход) в исполняемой программе.

� Вероятность предсказания переходов в современных

процессорах превышает 0.9.

Page 4: Оптимизация ветвлений и циклов › teaching › uploads › HPC › hpcs-lecture2.pdf · Лекция 2: Оптимизация ветвлений и циклов

Branch Prediction Unit (BPU)

44

� Статическое предсказание (Static prediction)

Фиксированное правило работы предсказателя –

условный переход либо выполняются всегда, либо не

выполняются никогда.

� Ранние SPARC, MIPS: условные переходы никогда не

выполняются;

� Современные CPU: обратный переход (переход на

более младшие адреса), является циклом и выполняется,

а любой прямой переход (на более старшие адреса),

не выполняется

Page 5: Оптимизация ветвлений и циклов › teaching › uploads › HPC › hpcs-lecture2.pdf · Лекция 2: Оптимизация ветвлений и циклов

Статическое предсказание переходов

55

Intel 64 and IA-32 Architectures Optimization

Reference Manual

� Процессоры Pentium 4, Pentium M, Intel Core Solo и Intel

Core Duo имеют схожие алгоритмы статического

предсказания переходов:

o безусловные переходы выполняются

o косвенные переходы (indirect jump, jmp *%eax)

не выполняется

o условные переходы предсказываются динамическим

алгоритмом (даже при первом выполнении)

Page 6: Оптимизация ветвлений и циклов › teaching › uploads › HPC › hpcs-lecture2.pdf · Лекция 2: Оптимизация ветвлений и циклов

Динамическое предсказание переходов

66

� Динамическое предсказание (Dynamic prediction) –

такие методы осуществляют накопление и анализ истории

ветвлений.

� Информация о предыдущих ветвлениях хранится

в буфере предсказания переходов (Branch Target Buffer)

0xFF01 l1: movl %ebx, %eax

0xFF02 cmpl $0x10, %eax

0xFF03 jne l2

0xFF04 mov %eax, %ecx

0xFF05 jmp l3

0xFF06 l2: mov $-0x1, %ecx

0xFF07 l3:

0xFF08 cmpl $0xFF, %ebx

0xFF09 jne l1

Addr

(low bits)

History Target

0xFF03 1 0xFF06

0xFF09 0

Page 7: Оптимизация ветвлений и циклов › teaching › uploads › HPC › hpcs-lecture2.pdf · Лекция 2: Оптимизация ветвлений и циклов

1-bit dynamic predictioner

77

Record Branch history Target

0 1 0xAF06

1 0 0x1134

2 1 0x01FC

3 0 0xFF06

...

2k – 1 1 0xBEAF

Адрес

инструкции

перехода

0011

63 0k бит

Branch

predictor

Page 8: Оптимизация ветвлений и циклов › teaching › uploads › HPC › hpcs-lecture2.pdf · Лекция 2: Оптимизация ветвлений и циклов

Taken

1-bit dynamic predictioner

88

Not

takenTaken

1 0

Not taken

Taken

Not taken

Page 9: Оптимизация ветвлений и циклов › teaching › uploads › HPC › hpcs-lecture2.pdf · Лекция 2: Оптимизация ветвлений и циклов

Taken

1-bit dynamic predictioner

99

Not

takenTaken

1 0

Not taken

Taken

Not taken

for (i = 0; i < 9; i++)

{

/* code */

}

movl $0, %ecx

jmp .L2

.L1:

/* code */

addl $1, %ecx

.L2: cmpl $8, %ecx

jle .L1

Page 10: Оптимизация ветвлений и циклов › teaching › uploads › HPC › hpcs-lecture2.pdf · Лекция 2: Оптимизация ветвлений и циклов

Taken

1-bit dynamic predictioner

1010

Not

takenTaken

1 0

Not taken

Taken

Not taken

i = 0, predicted 0, MISPREDICTION (state -> 1)

i = 1, predicted 1, OK, (state -> 1)

i = 2, predicted 1, OK, (state -> 1)

i = 3, predicted 1, OK, (state -> 1)

...

i = 9, predicted 1, MISPREDICTION (state -> 0)

80% ветвлений

предсказано

корректно

Page 11: Оптимизация ветвлений и циклов › teaching › uploads › HPC › hpcs-lecture2.pdf · Лекция 2: Оптимизация ветвлений и циклов

Taken

1-bit dynamic predictioner

1111

Not

takenTaken

1 0

Not taken

Taken

Not taken

for (i = 0; i < 9; i++) {

if ((i & 1) == 0)

/* Code 1 */

else

/* Code 2 */

}

Page 12: Оптимизация ветвлений и циклов › teaching › uploads › HPC › hpcs-lecture2.pdf · Лекция 2: Оптимизация ветвлений и циклов

Strongly

not taken

Saturating counter (2-bit, Bimodal predictor)

1212

Weakly

not takenWeakly

taken

Strongly

taken

Not taken

00 01 10 11State:

Taken Taken TakenTaken

Not taken Not taken Not taken

� При выполнении перехода состояние увеличивается на 1

� При невыполнении перехода состояние уменьшается на 1

� Прогноз: если состояние 00 или 01, то переход не состоится,

иначе состоится

� Использовался в Intel Pentium (не MMX версии)

Page 13: Оптимизация ветвлений и циклов › teaching › uploads › HPC › hpcs-lecture2.pdf · Лекция 2: Оптимизация ветвлений и циклов

Two-level adaptive predictor

1313

Page 14: Оптимизация ветвлений и циклов › teaching › uploads › HPC › hpcs-lecture2.pdf · Лекция 2: Оптимизация ветвлений и циклов

Branch prediction in Intel Core2

1414

� Для предсказания условных переходов используется

гибридный предсказатель (hybrid predictor) включающий

двухуровневый предсказатель (8 битный глобальный

буфер) и счетчик циклов (loop counter)

� Misprediction penalty: 15 clock cycles

Page 15: Оптимизация ветвлений и циклов › teaching › uploads › HPC › hpcs-lecture2.pdf · Лекция 2: Оптимизация ветвлений и циклов

Ветвления в программах

1515

if (x == 0)

else if (x == 1)

else

switch (x) {

case 0:

break;

case 1:

break;

default:

}

for (i = 0; i < 10; i++) {

}

while (data > 0) {

data--;

}

do {

data--;

} while (data > 0);

Page 16: Оптимизация ветвлений и циклов › teaching › uploads › HPC › hpcs-lecture2.pdf · Лекция 2: Оптимизация ветвлений и циклов

11 переходов

(условие вне цикла

и 10 его итераций)

20 переходов

(условие цикла и

ветвление в его теле)

/* Исходный фрагмент */

for (i = 0; i < 10; i++) {

if (value > 10)

data++;

else

data--;

}

/* Модифицированная версия */

if (value > 10) {

for (i = 0; i < 10; i++)

data++;

} else {

for (i = 0; i < 10; i++)

data--;

}

Типовые ошибки

1616

Page 17: Оптимизация ветвлений и циклов › teaching › uploads › HPC › hpcs-lecture2.pdf · Лекция 2: Оптимизация ветвлений и циклов

Типовые ошибки

1717

void MyFunc(int size, int blend, float *src,

float *dest, float *src_1, ...)

{

int j;

for (j = 0; j < size; j++) {

if (blend == 255)

dest[j] = src_1[j];

else if ( blend == 0 )

dest[j] = src_2[j];

else

dest[j] = (src_1[j] * blend + src_2[j]

* (255 - blend)) / 256;

}

}

Page 18: Оптимизация ветвлений и циклов › teaching › uploads › HPC › hpcs-lecture2.pdf · Лекция 2: Оптимизация ветвлений и циклов

Типовые ошибки

1818

void MyFunc (int size, int blend, float *src,

float *dest, float *src_1, ... )

{

int j;

if (blend == 255) /* Инвариантное ветвление */

for (j = 0; j < size; j++)

dest[j] = src_1[j];

else if (blend == 0)

for (j = 0; j < size; j++)

dest[j]= src_2[j];

else

for (j = 0; j < size; j++)

dest[j] = (src_1[j] * blend + src_2[j]

* (255-blend)) / 256;

}

Page 19: Оптимизация ветвлений и циклов › teaching › uploads › HPC › hpcs-lecture2.pdf · Лекция 2: Оптимизация ветвлений и циклов

Типовые ошибки

1919

void fun()

{

if (t1 == 0 && t2 == 0 && t3 == 0) {

/* Code 1 */

} else {

/* Code 2 */

}

}

cmpl $0, -4(%rbp)

jne .L2

cmpl $0, -8(%rbp)

jne .L2

cmpl $0, -12(%rbp)

jne .L2

/* Code 1 */

jmp .L3

.L2:

/* Code 2 */

.L3:

3 ветвления

Page 20: Оптимизация ветвлений и циклов › teaching › uploads › HPC › hpcs-lecture2.pdf · Лекция 2: Оптимизация ветвлений и циклов

Типовые ошибки

2020

void fun()

{

if ((t1 | t2 | t3) == 0) {

/* Code 1 */

} else {

/* Code 2 */

}

}

movl -8(%rbp), %eax

movl -4(%rbp), %edx

orl %edx, %eax

orl -12(%rbp), %eax

testl %eax, %eax

jne .L2

movl $133, -16(%rbp)

jmp .L3

.L2:

movl $333, -16(%rbp)

.L3:

1 ветвление

Page 21: Оптимизация ветвлений и циклов › teaching › uploads › HPC › hpcs-lecture2.pdf · Лекция 2: Оптимизация ветвлений и циклов

GCC branch annotation

2121

#define likely(x) __builtin_expect (!!(x), 1)

#define unlikely(x) __builtin_expect (!!(x), 0)

const char *home;

home = getenv("HOME");

if (likely(home))

printf("Your home is %s\n", home);

else

fprintf (stderr, "HOME not set!\n");

Page 22: Оптимизация ветвлений и циклов › teaching › uploads › HPC › hpcs-lecture2.pdf · Лекция 2: Оптимизация ветвлений и циклов

Расщепление циклов (Loop splitting)

2222

void fun()

{

for (i = 0; i < n; i++) {

v1[i] = 0;

v2[i] = 0;

/* ... */

vN[i] = 0;

}

}

Page 23: Оптимизация ветвлений и циклов › teaching › uploads › HPC › hpcs-lecture2.pdf · Лекция 2: Оптимизация ветвлений и циклов

Расщепление циклов (Loop splitting)

2323

void fun()

{

for (i = 0; i < n; i++) {

v1[i] = 0;

v2[i] = 0;

}

for (i = 0; i < n; i++) {

v3[i] = 0;

v4[i] = 0;

}

/* ... */

}

Page 24: Оптимизация ветвлений и циклов › teaching › uploads › HPC › hpcs-lecture2.pdf · Лекция 2: Оптимизация ветвлений и циклов

Слиянии циклов (Loop fusion)

2424

void fun()

{

for (i = 0; i < n; i++) {

v1[i] = 0;

}

for (i = 0; i < n; i++) {

v2[i] = 0;

}

}

Page 25: Оптимизация ветвлений и циклов › teaching › uploads › HPC › hpcs-lecture2.pdf · Лекция 2: Оптимизация ветвлений и циклов

Слиянии циклов (Loop fusion)

2525

void fun()

{

for (i = 0; i < n; i++) {

v1[i] = 0;

v2[i] = 0;

}

}

Page 26: Оптимизация ветвлений и циклов › teaching › uploads › HPC › hpcs-lecture2.pdf · Лекция 2: Оптимизация ветвлений и циклов

Разворачивание циклов (Loop unrolling)

2626

enum { n = 40 * 1024 * 1024 };

int main()

{

int *p;

int i, sum;

p = (int *)malloc(sizeof(*p) * n);

for (i = 0; i < n; i++)

p[i] = rand();

for (sum = 0, i = 0; i < n; i++) {

sum += p[i];

}

return 0;

}

Page 27: Оптимизация ветвлений и циклов › teaching › uploads › HPC › hpcs-lecture2.pdf · Лекция 2: Оптимизация ветвлений и циклов

Зависимость по данным

между инструкциями

enum { n = 40 * 1024 * 1024 };

int main()

{

int *p;

int i, sum;

p = (int *)malloc(sizeof(*p) * n);

for (i = 0; i < n; i++)

p[i] = rand();

for (sum = 0, i = 0; i < n; i += 4) {

sum += p[i];

sum += p[i + 1];

sum += p[i + 2];

sum += p[i + 3];

}

return 0;

}

Разворачивание циклов (Loop unrolling)

2727

Page 28: Оптимизация ветвлений и циклов › teaching › uploads › HPC › hpcs-lecture2.pdf · Лекция 2: Оптимизация ветвлений и циклов

Разворачивание циклов (Loop unrolling)

2828

enum { n = 40 * 1024 * 1024 };

int main()

{

int *p;

int i, sum, t1, t2, t3, t4;

/* Initialization code ... */

t1 = t2 = t3 = t4 = 0;

for (sum = 0, i = 0; i < n; i += 4) {

t1 += p[i];

t2 += p[i + 1];

t3 += p[i + 2];

t4 += p[i + 3];

}

sum = t1 + t2 + t3 + t4;

return 0;

}

Page 29: Оптимизация ветвлений и циклов › teaching › uploads › HPC › hpcs-lecture2.pdf · Лекция 2: Оптимизация ветвлений и циклов

Разворачивание циклов (Loop unrolling)

2929

void fun()

{

for (i = 0; i < 1024; i++) {

if (i & 0x01)

fun_a(i);

else

fun_b(i);

}

}

Page 30: Оптимизация ветвлений и циклов › teaching › uploads › HPC › hpcs-lecture2.pdf · Лекция 2: Оптимизация ветвлений и циклов

Разворачивание циклов (Loop unrolling)

3030

void fun()

{

for (i = 0; i < 1024; i += 2) {

fun_a(i);

fun_b(i + 1);

}

}

Page 31: Оптимизация ветвлений и циклов › teaching › uploads › HPC › hpcs-lecture2.pdf · Лекция 2: Оптимизация ветвлений и циклов

Перестановка циклов

3131

void fun()

{

for (i = 0; i < 4; i++) {

a[i] = 0;

for (j = 0; j < 4; j++) {

a[i] += b[j][i];

}

}

}

Page 32: Оптимизация ветвлений и циклов › teaching › uploads › HPC › hpcs-lecture2.pdf · Лекция 2: Оптимизация ветвлений и циклов

Перестановка циклов: расщепление

3232

void fun()

{

for (i = 0; i < 4; i++)

a[i] = 0;

for (i = 0; i < 4; i++) {

for (j = 0; j < 4; j++) {

a[i] += b[j][i];

}

}

}

Page 33: Оптимизация ветвлений и циклов › teaching › uploads › HPC › hpcs-lecture2.pdf · Лекция 2: Оптимизация ветвлений и циклов

Перестановка циклов: перестановка

3333

void fun()

{

for (i = 0; i < 4; i++)

a[i] = 0;

for (j = 0; j < 4; j++) {

for (i = 0; i < 4; i++) {

a[i] += b[j][i];

}

}

}

Page 34: Оптимизация ветвлений и циклов › teaching › uploads › HPC › hpcs-lecture2.pdf · Лекция 2: Оптимизация ветвлений и циклов

Hardware Performance Counters

3434

� PAPI

� $ perf list

cpu-cycles OR cycles [Hardware event]

instructions [Hardware event]

cache-references [Hardware event]

cache-misses [Hardware event]

branch-instructions OR branches [Hardware event]

branch-misses [Hardware event]

bus-cycles [Hardware event]

ref-cycles [Hardware event]

Page 35: Оптимизация ветвлений и циклов › teaching › uploads › HPC › hpcs-lecture2.pdf · Лекция 2: Оптимизация ветвлений и циклов

Profilers

3535

Sampling {Static, Binary}

Instrumentation

� Perf, Valgrind, Intel Vtune, OProfile

$ perf stat –e branch-misses ./loopunrolling

Performance counter stats for './loopunrolling':

709.737801 task-clock # 0.995 CPUs utilized

81 context-switches # 0.114 K/sec

5 CPU-migrations # 0.007 K/sec

2,379 page-faults # 0.003 M/sec

2,106,950,459 cycles # 2.969 GHz

398,589,229 branches # 561.601 M/sec

1,280,498 branch-misses # 0.32% of all