C++ and other lectures
10K subscribers
56 photos
3 files
295 links
Учебный канал в Телеграм: тут будут анонсы и ссылки на лекции и стримы.

Написать автору: @Tilir

Boosty автора: https://boosty.to/cpp_lects_rus
Download Telegram
Первая лекция второй части моего англоязычного курса по С++ доступна на Youtube.

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

Эта лекция начинает глубокое погружение в аллокаторы C++. Мы начнём с глобального (C-style) выделения памяти и исторической мотивации появления пользовательских аллокаторов в раннем C++. Затем разберём две фундаментальные проблемы их дизайна -- взаимозаменяемость и переход между разными типами аллокаторов. Через серию практических примеров -- включая freelist allocator -- мы исследуем, что именно идет не так на практике, почему дизайн аллокаторов оказывается неожиданно тонким и сложным, и как разделяемое состояние и правила продвижения аллокаторов усложняют реализацию контейнеров. Далее мы рассмотрим идею отделения стратегии выделения памяти от самих контейнеров, закладывая основу arena-based подхода, и проанализируем проблемы управления локальными аллокаторами внутри контейнеров. Эти проблемы впоследствии мотивировали изменения стандарта, но это мы оставим на следующую лекцию.

Timeline:
00:00 Начало. Пара слов про глобальные (C-style) аллокаторы.
04:51 Мотивация аллокаторов в раннем C++
09:49 Две важные проблемы: Interchangability и Rebinding
14:43 Logging Allocator Case Study
19:25 Weasel Words and C++11 Allocators Motivation
28:10 Case Study: Freelist Allocator и его проблемы
40:04 Разбор и починка причин проблем: Shared Freelist
52:10 Separating Resource: основы Arena-Based подхода
55:00 Case Study: Small Vector
01:01:38 Allocator Instances Hell: Halpern's Case and Scoped Allocators
01:08:26 Проблемы классических аллокаторов, тизер на следующую лекцию и список литературы.

#cpp_postgraduate
🔥35👍21❤14🤮1
Выложил вторую часть лекции по аллокаторам на английском языке.

https://youtu.be/naiLRcS3chU

Эта лекция продолжает наше обсуждение аллокаторов в C++. Мы начнём с идеи memory_resource и внезапно выясним, что полиморфизм времени выполнения оказывается неожиданно удобным инструментом для его реализации. Затем мы разбираем стандартные ресурсы, поставляемые библиотекой — такие как monotonic и multipool resources — и посмотрим, как они используются через polymorphic_allocator и контейнеры семейства PMR. Далее мы реализуем простой тестовый memory resource, чтобы посмотреть, как именно проходят выделения памяти через PMR и что такое стандартный ресурс по умолчанию. После этого, на примере известного примера Пабло Халперна с односвязным списком, мы разберём, как аллокаторы взаимодействуют с дизайном контейнеров, включая вопросы big-five и правила распространения аллокаторов. В конце мы проведём сравнение стоимости разработки при различных подходах к абстракции аллокатора.

00:00 Introduction: runtime polymorphism for memory_resource
06:15 Standard resources: monotonic and multipool
12:15 Polymorphic allocator and PMR containers
19:16 Test memory_resource: PMR and the default resource
25:52 Halpern example: slist and its design details
31:40 Allocators and the Big Five for slist
40:22 Exception safety strikes back
46:00 Preserving noexcept in the move constructor
53:06 Why are we not afraid of virtual calls?
56:53 Halpern's table, final thoughts, and bibliography

#cpp_postgraduate
🔥33❤10👍6🥰2🤮2
Выложил лекцию по умным указателям на английском языке.

https://youtu.be/6w_1HcLoeg4

В этой лекции мы обсудим умные указатели в C++ и то, как они помогают управлять различными ресурсами, включая память. Мы начнём с перечисления альтернатив, включающих семантику значения и разные виды умных указателей, и в ходе лекции разберём детали каждого из них. Отдельно мы остановимся на двух основных механизмах, предоставляемых стандартной библиотекой C++ -- уникальных указателях и разделяемых указателях. В случае уникальных указателей мы также протянем связь с прошлой лекцией и обсудим, как они взаимодействуют с аллокаторами. Для разделяемых указателей мы рассмотрим типичные проблемы общего владения: циклические ссылки, использование weak_ptr, aliasing-конструкторы, enable_shared_from_this, а также распространённые ошибки вроде создания нескольких контрольных блоков для одного объекта. Завершим лекцию несколькими тизерами применения разделяемых указателей в многопоточной среде.

00:00 Введение: семантика значения и альтернативы для умных указателей.
08:05 Некопируемые неперемещаемые значения и prvalue elision.
11:35 Перемещаемые объекты и их возврат из функций.
18:05 Тонкости make_unique и организация делетера.
25:16 Unique pointers и аллокаторы.
32:15 Мотивация и проектирование разделяемых указателей.
38:59 Проблема владения контрольным блоком и расползание разделяемых указателей по коду.
47:50 Ковариантность разделяемых указателей и снова делетеры.
56:30 Зацикливание разделяемых указателей и weak pointers.
01:04:22 Настоящая стоимость make_shared.
01:08:30 Тизеры относительно применения в многопоточности, список литературы, завершение.

#cpp_postgraduate
👍41❤15🔥11🤮1
Выложил лекцию по динамическому полиморфизму на английском языке.

https://youtu.be/-hAxKYFY_7c

В этой лекции мы поговорим про динамический полиморфизм в C++ -- одну из самых неоднозначных и часто неправильно понимаемых тем языка. Мы обсудим, зачем он вообще нужен, какие реальные задачи он решает и почему полностью отказаться от него не получается. Разберём классическую реализацию через виртуальные функции, их стоимость, ограничения и подводные камни -- включая множественное наследование, RTTI и dynamic_cast. Далее мы рассмотрим альтернативы: CRTP и ручное управление таблицами диспетчеризации, их плюсы и минусы. В конце придём к более современным подходам -- инверсии полиморфизма и семантике значения в духе Шона Парента, где динамический полиморфизм скрыт внутри и не протекает в пользовательский код. Лекция оставляет открытым вопрос о том, как же правильно сочетать языковые механизмы и библиотечные абстракции и есть ли у динамического полиморфизма окончательное решение в современном C++.

00:00 Введение, мотивация для динамического полиморфизма.
03:40 Виртуальные функции и полиморфные интерфейсы.
12:22 Альтернатива: интерфейсы через CRTP.
16:25 CRTP mixins и немного deducing this.
24:45 Множественное наследование и симметрия RTTI-механизмов.
31:00 Виртуальное наследование.
37:06 dynamic_cast и его три смысла.
46:45 Снова о мотивации рантайм-полиморфизма и критика виртуальных функций.
51:18 Проблема Дионне и её разнообразные решения.
01:00:50 Решение Шона Парента: переиспользование и скрытие полиморфизма.
01:04:00 Открытый финал и список литературы.

#cpp_postgraduate
🔥52❤11😱8👍3
Выложил первую лекцию по многопоточности на английском языке.

https://youtu.be/Z5BJyUfPivg

В этой лекции мы начнём длинный путь в многопоточность на C++. Мы стартуем с самых основ. Обсудим, что такое поток исполнения в модели языка, чем логическая многопоточность отличается от аппаратного параллелизма, что такое область памяти и как возникает гонка данных. Разберём, почему наивные решения, вроде volatile или привязки потоков к ядрам, не решают проблему синхронизации. Далее мы перейдём к базовым примитивам синхронизации -- мьютексам -- и обсудим, как их использовать с помощью RAII. Нам придётся ввести концепцию безопасности относительно потоков, подобно тому, как в языке существует понятие безопасности относительно исключений. На примере простого буфера мы увидим, как легко получить ошибки проектирования даже при "очевидной" защите довольно простого класса, и введём понятие API race. В завершение мы рассмотрим одну из классических проблем -- дедлоки -- и разберём задачу об обедающих философах как иллюстрацию того, насколько сложной может быть корректная синхронизация и как язык C++ нас в этом поддерживает.

Timeline
00:00 Введение. Что такое поток исполнения?
08:14 Области памяти и гонка (data race).
14:18 Немного про volatile и почему это плохое решение.
18:38 Немного про POSIX affinity и почему это плохое решение.
26:00 Базовая синхронизация: mutex.
30:43 Безопасность относительно исключений и безопасность относительно потоков.
37:07 Попытка построить thread-safe буфер.
41:45 API races как проблема проектирования безопасных контейнеров.
52:20 Deadlocks и Dining Philosophers.
01:00:06 Завершение и список литературы.

#cpp_postgraduate
👍50🔥34❤7
Выложил вторую лекцию по многопоточности на английском языке.

https://youtu.be/kup0qSuJTKM

Во второй лекции мы продолжим разбирать примитивы синхронизации в C++ и перейдём от базовых мьютексов к более сложным механизмам взаимодействия между потоками. Начнём мы с одноразовых событий и связанного с ними классического антипаттерна DCL. Далее мы рассмотрим передачу сигналов между потоками, введём для этого условные переменные и разберём типичные подводные камни, включая спонтанные пробуждения и связанные с ними ошибки. Отдельно обсудим, почему такие ошибки сложно отлаживать и как в этом помогает инструмент strace. Затем мы рассмотрим разделяемые блокировки, обсудим модель их использования и разберём, почему они не являются бесплатным ускорением. В завершение нас ждут ещё несколько антипаттернов, включая рекурсивные мьютексы и мьютексы с ограничением времени. Также мы оценим реальные размеры примитивов синхронизации и их влияние на производительность.

Timeline
00:00 Введение. Одноразовые события.
04:50 Антипаттерн DCL и решение через std::once_flag
12:50 Условные переменные и коммуникация между потоками.
19:15 Внезапные пробуждения на условных переменных.
27:14 Проблемы отладки и полезность strace.
31:22 Разделяемые блокировки.
37:45 Бенчмаркинг разделяемых блокировок: no free lunch.
43:04 Бенчмаркинг: лучший случай для разделяемых блокировок.
50:38 Антипаттерны: recursive_mutex и timed_mutex.
55:47 Размер основных примитивов, завершение, литература.

#cpp_postgraduate
❤22🔥16👍11🌚1🌭1
Выложил лекцию по многопоточным очередям на английском языке.

https://www.youtube.com/watch?v=86aNZgS9SOU

В этой лекции мы завершаем обсуждение lock-based примитивов синхронизации в C++ и подводим итог всему, что связано с классическим многопоточным программированием на мьютексах и condition variables. Мы рассмотрим producer–consumer паттерн, реализуем ограниченные MPMC-структуры (стек и очередь), разберём типичные проблемы таких решений и попробуем их исправить. Отдельно обсудим, почему даже "правильные" на первый взгляд интерфейсы могут приводить к потере задач. Далее перейдём к более выразительным механизмам коммуникации между потоками: future/promise, обработке исключений, packaged_task и std::jthread. Посмотрим, как современные абстракции позволяют писать более чистый и безопасный код. В завершение попробуем объединить всё вместе и построить очередь с произвольными задачами.

Timeline
00:00 Введение. Ментальная модель мьютекса.
06:33 Thread-Safe Lock-Based Bounded MPMC Stack.
11:01 Измеряем производительность и обнаруживаем проблему.
18:00 Пробуем пофиксить проблему: Wake and Done.
22:30 Thread-Safe Lock-Based Bounded MPMC Queue.
29:00 Критика интерфейса: очередь, которая не может не терять задачи.
33:46 Что если мы позволим неограниченный размер?
36:52 Возврат данных из потока и механизм future/promise.
42:45 Обработка исключений в потоках.
46:43 Packaged Tasks and Joinable Threads.
51:28 Проблема постановки барьера.
57:46 MPMC Queue с произвольными задачами.
01:03:26 Задача на подумать и список литературы.

#cpp_postgraduate
🔥38👍10❤6💩1
Выложил первую лекцию по атомикам на английском языке.

https://youtu.be/dRlOwdj8BHI

В этой лекции мы начнём переход к настоящему lock-free программированию. Для этого нам понадобится серьёзная база в атомиках C++. Первое, что мы сделаем в начале лекции, -- это мотивируем атомик через конкретный пример контрольного блока shared_ptr и убедительный бенчмаркинг. Далее, рассматривая обычный инкремент, мы изобретём идиому Compare-And-Swap (CAS). Центральным понятием лекции является lock-freeness. Мы разберём иерархию гарантий прогресса, а также вернёмся к классическим антипаттернам, вроде double-checked locking, и покажем, как их корректно реализовать с помощью атомиков. Отдельно обсудим статическую инициализацию и thread-local переменные. Во второй половине лекции мы перейдём к более сложной теме -- API races. Посмотрим, как такие ошибки возникают даже при использовании атомиков, и почему их сложно обнаружить, в частности обсудим подход через формальную верификацию. Закончим мы разбором ситуаций активной блокировки.

Timeline
00:00 Intro. Контрольный блок для разделяемого указателя и снова data race.
04:30 Проблема контрольного блока. Бенчмаркинг atomic vs mutex.
10:25 Дуальность синхронизации. Какой единственный тип должен быть действительно атомарным.
17:30 Проблема инкремента для аомика. Мотивация для CAS.
28:24 Концепция lock-freeness и иерархия свободы.
38:45 Снова антипаттерн DCL. Чиним через атомики.
45:10 Синглтон Майерса: синхронизация вокруг статических переменных. Thread local переменные.
50:15 Снова Copy On Write: проблемы в простом COW подходе.
56:57 Поиск API Races в коде, активно использующем атомики.
01:04:30 Методы формальной верификации для поиска API races.
01:08:46 Завершение: livelocks и литература.

#cpp_postgraduate
👍47🔥23❤7💩1
Выложил вторую лекцию по атомикам на английском языке.

https://youtu.be/hikc1u-zOhQ

Во второй лекции по атомикам мы в основном сосредоточимся на моделях памяти в C++ и на том, как они соотносятся с реальной аппаратурой. Поговорим про переупорядочивание, happens-before и о том, почему без этого невозможно понять поведение многопоточного кода. Подробно рассмотрим модели памяти для атомиков и покажем, как relaxed легко приводит к неожиданным эффектам и даже UB, а также где он действительно полезен. Детально разберём барьеры памяти -- как они работают и как их можно воспроизводить вручную. Отдельно обсудим, почему атомики иногда тяжелее, чем кажется, и как атомики в C++ конкурируют с инлайн-ассемблером. В конце познакомимся с "теорией относительности" и разберём последовательные и непоследовательные модели.

Timeline
00:00 Начало. Переупорядочение повсюду.
09:15 Модели памяти в аппаратуре.
15:40 Отношение "happens after / before" в C++ и его корни.
21:05 Модели памяти атомиков в C++. Когда relaxed ведёт к UB.
29:09 Барьеры своими руками
36:25 Соревнуемся с инлайн-ассемблером.
41:12 Теория относительности.
47:33 Немного про Multithread COW Disease, литература и завершение.

#cpp_postgraduate
👍30🔥17❤13
Выложил третью лекцию по атомикам на английском языке.

https://youtu.be/h4k3z69aIMY

В третьей части лекции мы переходим к рассмотрению проблемы рекламации памяти и построению lock-free структур данных. Начинаем мы с рекламации памяти, разбирая в процессе, почему наивные решения на указателях и CAS ломаются, и где именно возникает необходимость аккуратно управлять временем жизни объектов. Далее рассматриваем новые подходы, которые введены в стандарт C++26: RCU и hazard pointers. Обсуждаем, как они работают, какие гарантии дают и какие накладные расходы вносят. После этого мы приступаем к рассмотрению lock-free структур данных. Сначала разбираем простой пример unbounded стека с использованием hazard pointers. Затем bounded MPMC стек, где появляются уже другие сложности: проблема публикации и проблема ABA. Разбираем, как они возникают и как с ними бороться. В завершение рассматриваем lock-free MPMC очередь, обсуждаем влияние моделей памяти на производительность и смотрим на результаты бенчмарков.

00:00 Введение. Проблема рекламации памяти.
07:03 Идея атомарного shared_ptr и её ограничения.
11:05 Решения в C++26: RCU.
23:01 Решения в C++26: Hazard pointers.
31:20 Lock-free unbounded stack с использованием hazard pointers.
35:45 Lock-free bounded MPMC stack: проблема публикации.
42:42 Проблема ABA и способы её решения.
54:40 Lock-free bounded MPMC queue, бенчмаркинг и литература.

#cpp_postgraduate
🔥26👍9❤8🍓2🌭1
Выложил первую лекцию по корутинам на английском языке.

https://youtu.be/wmrW6AkRo3c

В этой лекции мы начинаем с базового вопроса: что вообще такое корутина и чем она отличается от обычной функции или thread routine, а также обсуждаем исторический контекст и классификацию сопрограмм: стековые и встроенные (stackless), асимметричные и симметричные и т.д. Основная часть лекции посвящена внутреннему устройству корутин в C++20/23. Разбираем три ко-оператора, интерфейс promise_type, coroutine_handle, awaiters и их контракт. На протяжении лекции мы будем постепенно строить собственные корутинные абстракции -- несколько наивные, но полезные в образовательных целях. Когда основы станут ясны, мы обсудим более сложные вещи, например то, как через awaiters можно реализовать более сложные механизмы -- подписку на событие и пробуждение нескольких корутин на едином объекте синхронизации. Также мы кратко обсудим оператор co_await и возможности для его перегрузки.

00:00 Introduction. Программы, подпрограммы и thread routines.
10:11 Сопрограммы и их классификация. Stackful- и stackless-сопрограммы в C++.
15:41 Генераторы в Python и C++23.
22:10 Внутреннее устройство и строительные блоки сопрограмм. Ко-операторы.
27:25 Интерфейс promise_type и Hello World.
36:50 Напишем свой простой генератор.
45:00 Range-based-использование и когенерация.
50:40 Детали работы ко-операторов. Awaiters.
56:23 Case study: подписка на результат.
01:05:42 Оператор co_await, завершение и список литературы.

#cpp_postgraduate
🔥37👍7💯2❤1
Выложил вторую лекцию по корутинам на английском языке.

https://youtu.be/huitkyM1UQE

Во второй лекции мы переходим от базовой механики co_await и promise_type к более сложным и практическим аспектам программирования с использованием корутин в C++20/23. Сначала мы обсудим симметричные корутины, различные варианты await_suspend и то, как корутины могут напрямую передавать управление друг другу. Затем, на примере корутинной реализации конечных автоматов, разберём, как с помощью awaiters можно строить довольно сложные модели выполнения. Важной частью лекции является обсуждение взаимодействия корутин с потоками на примере многопоточной подписки на события. Мы разберём, почему встроенные (stackless) корутины могут продолжать выполнение на другом потоке, как устроен фрейм корутины и почему это создаёт сложности для оптимизаций в компиляторах. Также мы рассмотрим корутины как основу для композиции асинхронных вычислений и увидим, как корутины позволяют писать существенно более читаемый асинхронный код по сравнению с callback-based подходами. В завершение разберём внутреннее устройство корутин в компиляторах: фреймы корутин, порождаемые конечные автоматы и даже генерируемый ассемблер.

00:00 Введение. Вспоминаем пройденное.
04:38 Обобщаем awaitable transformations: что, кроме перегрузки co_await, нам доступно?
13:09 Изобретаем симметричные корутины в C++: await_suspend и его механика.
18:42 Case study: конечные автоматы на корутинах.
31:00 Монадические свойства co_await.
37:55 Сочетание корутин с потоками. Многопоточная подписка на события и её сюрпризы.
48:00 Корутинный интерфейс для std::future.
52:05 Корутины как механизм композиции асинхронных задач.
56:18 Внутреннее устройство корутин и их реализация в компиляторах.
01:02:04 Обзор литературы и завершение.

#cpp_postgraduate
🔥30👍21❤7
Выложил лекцию по GPGPU и SYCL на английском языке.

https://youtu.be/Ebj21eXDRDY

В этой лекции мы обсудим, почему модель программирования для графики и гетерогенных вычислений исторически отличается от обычного C++. Начнём с классических шейдерных языков, stateful memory, binding tables и адресных пространств, а затем перейдём к OpenCL и проблемам separate-source compute API. После этого разберём основы SYCL как примера single-source подхода к гетерогенному программированию, познакомимся с устройствами и очередями, а также с моделью исполнения SIMT. На примерах сложения векторов и перемножения матриц посмотрим, как часть работы отправляется на устройство и как SYCL описывает зависимости между вычислениями. Основная часть лекции посвящена памяти и синхронизации. Мы постепенно оптимизируем перемножение матриц и разбираем, как на производительность влияют разные виды памяти, tiled execution, барьеры и specialization constants. Затем обсудим гистограмму как пример конкурентного доступа к данным и поговорим об атомиках в GPU API. В финале вернёмся к C++ и обсудим природу указателей, а также generic address space в SYCL. На протяжении всей лекции нас будет сопровождать большое количество замеров производительности.

Timeline.
00:00 Введение. Гетерогенные вычисления и GPU как execution model.
03:50 Память в классических шейдерных языках на примере GLSL: stateful и stateless pointers.
10:35 Первые compute API с раздельными исходниками на примере OpenCL. Проблема небезопасности типов в API.
15:40 На пути к единому compute API: как расширять C++ для гетерогенного программирования?
19:34 Основы SYCL: очереди, command groups, iteration space и vector addition.
29:15 Перемножение матриц -- основная задача GPGPU.
35:28 Более интересное управление памятью: shared memory, device memory и снова аллокаторы.
40:25 Продолжаем умножать матрицы: приватная память, oneMKL и первые замеры.
45:15 Локальная память и барьеры. Инверсия параллелизма внутри рабочей группы.
52:52 Улучшаем перемножение матриц: tiled multiplication, specialization constants и ещё немного замеров.
59:52 Конкурентный доступ к данным: гистограмма, атомики и memory model в GPU API.
01:09:53 Обсуждение природы указателей, generic address space в SYCL, hierarchical parallelism и завершение лекции.

#cpp_postgraduate
👍41🔥26❤13👏2🙏1🫡1
Выложил лекцию по std::execution на английском языке. Это последняя, 28-я лекция англоязычного магистерского курса.

https://youtu.be/ZMcUTZppCAw

Финальная лекция магистерского курса по C++ посвящена std::execution -- новой модели исполнения, которая входит в C++26. Мы начнём с давно известных механизмов: параллельных алгоритмов стандартной библиотеки, ручного запуска потоков и std::async. На примере параллельного reduce посмотрим, почему этих средств быстро становится недостаточно, если хочется не просто запустить несколько потоков, но также аккуратно описывать и комбинировать вычисления. После этого перейдём к senders/receivers: разберём, что такое scheduler, sender, receiver и operation state, как работают адапторы и как вычисление может переходить между разными execution resources. Свяжем эту тему с миром GPGPU через bulk-вычисления, посмотрим на рекурсивное порождение асинхронных задач через execution scopes и обсудим разные варианты завершения вычислений. В конце поговорим о связи std::execution с корутинами, отмене задач через environment и ещё раз соберём общую картину: как C++26 предлагает описывать асинхронное и параллельное исполнение без ручного управления потоками.

Timeline
00:00 Введение. Параллельные алгоритмы в стандартной библиотеке.
03:30 Пишем собственный параллельный reduce.
10:05 std::async и его особенности. Замеры производительности.
16:50 Единая абстракция исполнения. Основы std::execution в C++26.
26:59 Концепт sender и адапторы.
35:00 Монадическая природа вычислений и let_value.
40:16 Адаптор bulk: снова заходим в мир GPGPU.
46:05 Параллельный reduce с использованием std::execution.
49:40 Execution scopes: динамическое создание задач. Параллельная сортировка.
54:41 Каналы в sender. Поведение upon_error и upon_stopped. Сигнатуры завершения.
01:02:19 Проверка completion signatures: упражнение в метапрограммировании и рефлексии.
01:06:50 Связь сендеров с корутинами: execution::task.
01:14:40 Снова многопоточная подписка и отмена задач.
01:18:47 Основные концепции ещё раз, список литературы и завершение.

#cpp_postgraduate
❤38🔥33👍14😢1
Немного подзамочного контента для моих уважаемых подписчиков.

Ни для кого не секрет, что мой магистерский курс этого года я записывал на английском языке. Меньше людей знает, что исходно он читался на русском языке, на английский я (нейронкой) до лекции переводил только слайды. Далее я брал другую нейронку, распознавал свой голос с записи лекции на русском, грузил вместе со слайдами в третью нейронку и просил сделать мне подстрочник на английском и с этого подстрочника на английском уже и читал.

И, конечно, я просил нейросеть убрать из этого подстрочника все шутейки, хиханьки, хаханьки, общение с аудиторией и всё остальное. В процессе ещё и правил все ошибки, которые находили на лекциях. Поэтому мой магистерский на английском немного высушен.

Чисто для моей аудитории, готовой, прямо скажем, на многое, выкладываю ссылки на магистерский курс этого года на русском. Предупреждаю: это очень фанатский контент. Не надо даже пробовать его потреблять, если вы привыкли к той лакированной подаче, которую я считаю нормой для своего ютуба.

Это вторая часть выкладки.

Have fun.

Лекции 1-14: https://xn--r1a.website/cpp_lects_rus/333

Лекция 15. Аллокаторы, часть 1
Лекция 16. Аллокаторы, часть 2
Лекция 17. Умные указатели
Лекция 18. Полиморфизм
Лекция 19. Потоки, часть 1
Лекция 20. Потоки, часть 2
Лекция 21. Очереди
Лекция 22. Атомики, часть 1
Лекция 23. Атомики, часть 2
Лекция 24. Атомики, часть 3
Лекция 25. Корутины, часть 1
Лекция 26. Корутины, часть 2
Лекция 27. SYCL и GPGPU
Лекция 28. Execution

Да, все ссылки на rutube, я стримил туда.

#cpp_postgraduate
🔥189❤71👍22🙏3😁1👾1