Ще говорим до голяма степен за тези 3%
Ще говорим за фундаментални принципи, а не за алгоритми
Ще се фокусираме върху по-low-level концепции и няма да говорим за multi-threading.
Ще говорим за хардуер... поне отгоре-отгоре
Да се вземе шестия елемент от контейнер.
std::vector<int> v;
...
int sixth = v[6]; // !
Теоретична реална сложност: 1
std::list<int> l;
...
auto isixth = l.begin();
for(int i=0; i<6; ++i) ++isixth;
int sixth = *isixth; // !
Теоретична реална сложност: 6
Да съберат елементите от списък.
int sum = 0;
for(auto elem : container) sum += elem;
Теоретична реална сложност: n
point3 sum = {0, 0, 0};
for (const auto& elem : container) {
sum.x += elem.x;
sum.y += elem.y;
sum.z += elem.z;
}
Теоретична реална сложност: 3n
Константна сложност: 1000.
Линейна сложност: 100n.
...
Полезно да е имаме представа за реалната сложност и за размера на входа
Съвременният хардуер прави реалната сложност практически неизчислима
Но, все пак...
Кешът е памет близко до процесора
Cache levels - колкото по-близко, толкова по-бързо
RAM (→ L4?) → L3 → L2 → L1
От "Дай памет на адрес Х!" следват потенциално различни стратегии. Например:
4KB на L3 → 256B на L2 → 64B на L1
Колко ни струва това?
Разклонение в програмата
Разклонение в програмата
Чакането е скъпо
y,n,n,y,y,y,y,y__builtin_expect - леко безсмисленоСпекулативно изпълнение: Изпълнението на код, който може би не трябва да бъде изпълняван
if вече не е толкова страшен
Hammer time
Напускаме пределите на нашата програма и се отправяме в света на операционната система
sin, cos, qsort
std::vector::reserve)
rdtscwbinvd__builtin_???_???, _m_??, _mm_??#ifdef ту дъ рескюЗаслужава си да ги прегледате и може би да откриете неочаквани прозрения
... и как може да ни пореже
char* memory = new char[0x200];
if (something_false) {
char value = *(char*)(KERNEL_MEM_PTR);
int index = (value & 1) * 0x100;
puts(memory[index]);
}
measure_time_to_access(memory[0]);
measure_time_to_access(memory[0x100]);
Код от операционната система:
if (some_condition) {
hidden_val = hidden_data[N];
whatever = public_data[hidden_val]; // o_O
}
if(true) на същия частичен адресКод от операционната система:
if (some_condition) { // на кой адрес е това?
hidden_val = hidden_data[N];
whatever = public_data[hidden_val]; // o_O
}
if(true) на същия частичен адрес for(auto& elem : public_data) {
measure_time_to_access(elem);
}
Нямаше реални примери, но се откриха
Борислав Станимиров / ibob.github.io / @stanimirovb
Тази презентация е тук: http://ibob.github.io/slides/cpu-friendly-code-2-bg/
Презентацията е лицензирана с Creative Commons Признание 3.0