uz
Feedback
C++ and other lectures

C++ and other lectures

Kanalga Telegram’da o‘tish

Учебный канал в Телеграм: тут будут анонсы и ссылки на лекции и стримы. Написать автору: @Tilir Boosty автора: https://boosty.to/cpp_lects_rus

Ko'proq ko'rsatish
9 609
Obunachilar
+1224 soatlar
+157 kunlar
+9930 kunlar
Postlar arxiv
Выложил лекцию по 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

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

Выложил лекцию по 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

Не могу не поделиться самым веселым, на мой взгляд, примером из доклада великолепного Константина Владимирова. Он делал анонс доклада в своем tg канале. Пример вот такой:

template <auto T = []{}> 
struct S {};

S a; S b;
В чем тут цимес. У нас T - это лямбда. И если мы таким образом определяем переменные, то в тип S записываются разные лямбды, и у нас получаются два разных типа:

static_assert(
    !std::is_same_v<decltype(a), decltype (b)>
);
Если же мы явно укажем пустые треугольные скобки вот так:

S<> a, b;

static_assert(
    std::is_same_v<decltype(a), decltype (b)>
);
То типы, внезапно, станут одинаковыми. Ну, мы один раз объявили тип, и две переменные этого типа. А теперь вопрос в зал. А что если мы определим эти две переменные точно так же, как во втором варианте, но только без явного указания треугольных скобок?

S a, b;
Давайте вы попробуете угадать? Ставя треугольные скобки мы исключаем вывод типов. Мы явно указываем, какой тип мы используем. Но если у нас есть вывод типов, у нас компиляторы начинают вести себя по-разному. clang падает с ошибкой ``` error: template arguments deduced as 'S<(lambda at <source>:4:20){}>' in declaration of 'a' and deduced as 'S<(lambda at <source>:4:20){}>' in declaration of 'b' 7 | S a, b; ``` А gcc считает, что это два разных типа. ``` static_assert( !std::is_same_v<decltype(a), decltype (b)> ); ``` Пруф. Вцелом доклад Константина был просто прекрасным, и я, наверное, понатырю сюда еще примеров из его доклада через пару месяцев. А когда он выйдет в открытый доступ - обязательно дам ссылку. Я был просто в восторге от дурки, которую он показывал.

Отличный реакт и канал интересный. К слову. У моего доклада маловато оценок "супер" и пока что их можно ставить. Если у вас есть билет, зайти и кликнуть "оценить". Это намёк ))

Выложил вторую лекцию по корутинам на английском языке. 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

Всем привет. Кто идёт на C++ Russia из моих уважаемых подписчиков, обратите пожалуйста внимание на изменения в программе, внесённые в последний момент. https://cppconf.ru/schedule/table/#day-2 Теперь мой доклад открывает конференцию в субботу утром, а Антон Полухин закрывает в воскресенье вечером (ранее было наоборот). Поэтому, если вы хотите попасть на мой доклад, вам надо будет встать утром в субботу и не опоздать к получению бейджа. Я в вас верю )) #official

Минутка 3d-моделей. Ребята из Iridi прислали исходники Крыса Кейта (Кита?) с обложки моей книги. Выложил на boosty в бесплатный доступ чисто чтобы хранить поближе к собственно книжке. https://boosty.to/cpp_lects_rus/posts/7f9999a9-4249-4538-9ddb-40b9338fe40f #boosty #cppbook

Выложил первую лекцию по корутинам на английском языке. 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

Стрим на Boosty скоро подрубаю. После завершения тут размещу ссылку на запись. Подключайтесь: https://boosty.to/cpp_lects_rus/streams/video_stream #official #boosty

Выложил третью лекцию по атомикам на английском языке. 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

Очередной отчётный стрим на бусти проведу 3 мая в 19 часов по Москве. В программе: * Новые интересные факты про моего несосто
Очередной отчётный стрим на бусти проведу 3 мая в 19 часов по Москве. В программе: * Новые интересные факты про моего несостоявшегося менеджера Игоря. * Как меня разводили на смарт-контрактах. * Зачем был опрос про столы. * Когда новые главы книги, почему задержка. * А также любые ваши вопросы, которые можно накидать уже сейчас: https://www.donationalerts.com/r/cpp_lects_rus P. S. Ваша поддержка моей просветительской деятельности меня очень мотивирует: https://boosty.to/cpp_lects_rus Минимальная подписка для участия в стриме всего-то 128 рублей. Мне кажется для всех кто на этом канале вообще не деньги )) #official #boosty

У вас в офисе какая длина у вашего рабочего стола? Предполагаем что у стола три параметра: длина, высота и глубина. Если работаете из дома или из коворкинга, тоже сойдёт.
Anonymous voting

Выложил вторую лекцию по атомикам на английском языке. 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

Съездил в Нижний Тагил по приглашению компании Iridi с лекцией по RAII. В частности рассказал что-то и про новые RAII-обёртки
+4
Съездил в Нижний Тагил по приглашению компании Iridi с лекцией по RAII. В частности рассказал что-то и про новые RAII-обёртки в C++26: std::polymorphic и std::indirect. К сожалению нормальной записи не велось, поэтому запись экрана выкладываю на правах черновика. https://rutube.ru/video/491df36a93e245aaefa116026cf775ef Timeline: 00:00 Введение. Инварианты классов. 07:58 Инкапсуляция и ряд смежных наблюдений. 14:23 Big-5 и безопасность исключений. Изобретаем RAII. 25:15 RAII и Value-семантика. Мотивируем std::polymorphic. 37:43 Детали std::polymorphic и делаем систему открытой. 43:20 Немного о некопируемых типах. RVO. 50:03 Некоторые советы по работе с unique pointers. 55:26 PImpl и мотивация для std::indirect. 58:32 Shared pointers и их проблемы. 01:03:25 Завершение: пара слов про интрузивные указатели, литература, первые пара вопросов. Слайды: https://sourceforge.net/projects/cpp-lects-rus/files/conference-talks/raii.pdf/download Получил в подарок удивительно тёплую толстовку (я в ней на фотографии) и прекрасную статуэтку работы местных мастеров. Новость о событии на канале Iridi: https://t.me/iRidiummobileRu/2344 Спасибо Марату Гилязетдинову за его усилия в организации этой поездки и за короткую экскурсию по Тагилу после лекции. P. S. Также недавно был в Йошкар-Оле но там слишком уж хорошая запись, так что пост выложу когда придёт время её выкладки на youtube. P. P. S. Приближается лето — лучшая пора когда меня можно позвать в ваш город, в ваш университет или в офис вашей компании с лекцией, на встречу с читателями и т. п. Если вы человек, который способен организовать такого рода поездку (найти помещение, договориться с администрацией, привести аудиторию), пишите мне в лс. #official #author_event

Выложил первую лекцию по атомикам на английском языке. 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

Минутка дружественного пиара. В компании YADRO стартовал набор на программу стажировки Импульс. В этом году открыто более 30 направлений. В том числе: * Разработка на C++. * C, системное программирование. * Тестирование. * Математика и алгоритмы. * и много чего ещё. Возможна удалёнка или гибрид. Детали можно узнать на вебинарах 16 и 23 апреля. Регистрация уже доступна на сайте. https://edu.yadro.com/impulse #official

Выложил лекцию по многопоточным очередям на английском языке. 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

Ссылку на прошедший стрим и его таймлан размещу тут, когда обработается. Пока немного забавного take-away. На стриме был задан интересный вопрос. Я его докрутил до следующего примера.
int x;
int *p = &x;
x = 0;
std::thread t([p]{ *p = 42; });
t.join();
use(x);
Компилятору в этом коде кажется ничто не мешает трансформировать его примерно так:
int x;
int *p = &x;
std::thread t([p]{ *p = 42; });
x = 0;
t.join();
use(x);
И тем самым создать UB (data race). В лямбду уходит указатель, он не пересекается как область памяти, happens-before вроде нет и т.п. — На стриме я задумался и не нашёл что сказать, но сейчас после стрима я почитал стандарт и внезапно мы тут защищены.
The completion of the invocation of the constructor synchronizes with the beginning of the invocation of the copy of f.
https://eel.is/c%2B%2Bdraft/thread.thread.constr#6 Так что happens-before всё-таки есть, кто бы мог подумать )) Дмитрий, который задавал вопрос, FYI. #boosty #questions

Начинаем в 19 часов. https://boosty.to/cpp_lects_rus/streams/video_stream Пост временный, снесу по завершении стрима. #boosty #official.