Новости по-русски

Аннотация на доклад "Память – идеальная абстракция" с конференции C++Russia 2018

D3.ru 

https://www.youtube.com/watch?v=i87W3KyZgPw

Интереснейший доклад о том, как устроена память "внутри". Обычно в ВУЗах часть этой информации дается на программировании, другая — на операционных системах, а третья — на курсах типа "архитектура ЭВМ". Итак, доклад построен вокруг трех строчек кода:

1) int* ptr = new int;
2) *ptr = 42;
3) delete ptr;

В принципе, все это применимо к любому другому языку программирования. В первой строке мы выделяем динамическую память для хранения целого числа. Во второй — записываем по полученному адресу число 42. В третьей — освобождаем память. Но что же внутри? (ответ дается для архитектуры x86_64, операционной системы Linux и аллокатора jemalloc {один из хороших аналогов стандартному аллокатору}). Ниже краткое содержание доклада с таймингом:

7:40 — оказывается malloc работает по–разному для "маленьких" и "больших" объектов. У нас объект маленький....

9:30 — оказывается аллокатор поддерживает хитрую структуру данных для быстрого выделения памяти под объекты разных размеров — называется tcache. Для каждого размера есть что–то типа "обоймы" готовых объектов, откуда malloc может что–то "попросить".

11:05 — если же в "обойме" нет свободного объекта — то приходится идти в глобальную кучу и просить область памяти там. Для этого поддерживается глобальный для каждого потока объект управления памятью — Arena. Внутри арены, опять же, поддерживаются различные механизмы для выделения памяти под маленькие и большие объекты. Для маленьких (как у нас) — поддерживается структура данных Slab.

12:50 — показано как slab устроен внутри. Slab — это массив объектов одинакового размера + информация об их использовании. Он может дать свободный объект если таковой есть. При этом устроен так, что минимизируется объем метаданных для объекта. Slab создается несколько, все они хранятся в очереди. Если в Slab нет свободных объектов — создается новый Slab или ищется "свободный" в очереди. При поиске используется эвристика для борьбы с фрагментацией.

18:30 — но как создать новый Slab? — использовать malloc. Рекурсия, но проблем не возникнет, т.к. Slab — большой объект и для него будет использоваться другой механизм выделения памяти. Описывается подсистема управления большими объектами (Extent) — хитрая структура данных и алгоритм.

22:30 — если вдруг при выделении памяти под Slab (или другой большой объект) оказалось, что память процесса кончилась... Обращаемся к операционной системе за новым куском памяти с помощью вызова mmap, который дает процессу дополнительную область памяти.

24:10 — хорошая картинка, показано что мы уже сделали чтобы получить память.

Оказывается, что mmap так устроен, что выделил нам только виртуальную память, которая не обеспечена физической. Физическая память будет выделяться только при первом обращении к этой памяти. Тут мы дошли до второй строки нашего кода...

Тут же, оказывается, что куча — логически последовательная область памяти, но физически она такой не является (состоит из нескольких физических кусков памяти {страниц}). Значит нужен механизм для трансляции логических адресов в физические (PTE), рассказывается про страничную организацию памяти и как этим занимается процессор.

30:25 — все что описано выше — работает медленно, поэтому используется TLB — кэш над PTE.

32:05 — как работает освобождение памяти (третья строка кода). Проблема — нужно знать сколько памяти было выделено по указателю. Для этого в jemalloc используется структура данных rtree — глобальный объект с информацией об отображении адресов в метаданные аллокатора.

35:30 — рассказано как лучше вернуть память операционной системе и хитрый механизм с эвристикой, используемый в jemalloc.

40:00 — вопросы.

https://www.youtube.com/watch?v=i87W3KyZgPw

Написал rrrfer на programming.d3.ru / комментировать

Читайте на 123ru.net