Один микросек - C++, low latency, concurrency, HFT
824 subscribers
10 photos
2 videos
42 links
Download Telegram
В выходные готовился к воркшопу на C++ Russia 2024: продумывал как лучше объяснять, куда вставить различные нюансы, фишки, объяснения багов, дописывал нюансы в коде, добавлял readme, добавлял опциональные задачи, добавлял комментарии, улучшал тесты, копал тему еще глубже. Репозиторий пока скрыт, но по плану я открою его за сутки до начала.
В рамках воркшопа участники напишут Queue, Latch, RWLock. В качестве "домашнего задания" останется: написать свой Condition Variable на Futex'ах (непростая задача), и Thread Pool на основе написанного Queue. Ближайшие несколько постов будут про воркшоп.
👍65
Я вернулся из отпуска и командировки, отдохнул и готов писать дальше. Что произошло за три недели?

Во-первых, я провёл воркшоп на конференции C++ Russia. В целом, всё прошло хорошо: люди были довольны, судя по благодарностям и форме обратной связи. Были технические неполадки (в середине мероприятия пришлось переключить микрофон), и не успели решить две задачи из семи, учту на будущее.

Во-вторых, похоже, что один из преподов OTUS'а решил спиздить вдохновиться воркшопом. Об этом расскажу в следующем посте.

В-третьих, мы в своей небольшой команде выходим на новую крипто-полу-defi-биржу. Это интересное время, которое очень драйвит. Однако результата легко и быстро не получить. Первая реализация обычно не даёт денег, и требует дальнейшей долгой настройки, бэктестов, оптимизаций и исследований.
👍8
Теперь об OTUS'е и воркшопе. Как-то случайно я зашел в какой-то плюсовый канал и увидел рекламу открытого вебинара на знакомую тему "Условные переменные". "Интересно посмотреть о чем они расскажут" подумал я, перешёл на сайт и сильно удивился. Текст с описанием вебинара был очень и очень похож на тот, который я писал ранее. Сравните сами на скриншотах.

Я всё еще не могу утверждать, что содержимое будет один в один, ведь сам вебинар я ещё не видел, но ситуация напрягает. Если хочется взять задачи с воркшопа, то можно связаться со мной, спросить разрешения, пообсуждать варианты. Можно и своё сделать, это не что-то секретное.

Репозиторий с задачами, если интересно: https://github.com/Yukigaru/cpprussia-workshop-condition-variable
🤬12😢1
Один микросек - C++, low latency, concurrency, HFT
Теперь об OTUS'е и воркшопе. Как-то случайно я зашел в какой-то плюсовый канал и увидел рекламу открытого вебинара на знакомую тему "Условные переменные". "Интересно посмотреть о чем они расскажут" подумал я, перешёл на сайт и сильно удивился. Текст с описанием…
Со мной связались представители OTUS и сказали, что преподаватель увидел рекламу воркшопа, а потом затеял свой, и описание похоже, потому что "базовые составляющие этой темы плюс минус одни". Говорят, контент будет уникальным. Считаю, вопрос закрыт.
🥴10👍6😐1
А тем временем я затеял несколько воркшопов на новые темы (считай, понравилось, надо повторить). Из идей:

1) concurrency: mutexes (там тоже много интересного можно поделать, хотя казалось бы, мьютексы)

2) std sorting и ordering (sort, partial_sort, stable sort, nth_element, partition, lower/upper_bound, merge, компараторы, parallel sort, priority queue, heap).

3) gdb debugging (различные инструменты, отладка креш дампов, отладка без символов, форматтеры)
... (далее вырезано, чтобы не вдохновлять никого на вебинары с такой же темой)

Считаю, что самым сложным будет самостоятельено привлечь достаточное количество участников. Человек от 10, полагаю, будет достаточно, человек от 20 можно считать успехом. На cpprussia было ~45-50 участников, но у организаторов есть мощнейший ресурс для привлечения, и они даже ограничили количество сверху.

Технически будет так:
- собираемся в онлайн платформе (её подобрать еще нужно)
- даётся немного объяснений
- решаем задачи
- для шустрых есть доп. задачи
- после выдается большая задача на домашную работу
👍16🔥3
В нашем офисе желающим поставили подъемные столы с электромотором. Использую первый день, но предварительно могу сказать, что ощущается очень перспективно. Помогает сохранять бодрость. Не так сильно, как крэши на релизе, но тоже неплохо.

Пошуршал по интернету в поисках исследований, и нашел несколько: 1, 2, 3, 4. Все говорят о том, что standing desks чрезвычайно полезны для юзера:
- снижают субъективные ощущения дискомфорта и боли в спине, шее и плечах
- повышают продуктивность
- способствуют сжиганию жира
- улучшают объективные показатели кардиометаболического здоровья
😁4👍3
Что почитать по C++ и разработке в целом?

[easy] Comparison of the three implementations of std::string (MSVC, GCC, Clang), с погружением в то, как data(), size(), empty() обрабатывают два состояния (small/large string).

[easy] Какие ошибки есть в коде LLVM от PVS-Studio.

[easy] Практический туториал по x86_64 assembly, если хочется самому написать "hello, world" на asm'е.

[medium] Свежий (2024г) бенчмарк годных хэш-таблиц. Цитата для привлечения внимания: "std::unordered_map: This table is far slower than most of the open-addressing tables in most of the benchmarks".

[hard] How fast are Linux pipes, а так же как они устроены, с погружением в нюансы ядра.

[hard] Книга Сергея Слотина Algorithms for Modern Hardware (не законченная). Оцените по оглавлению, сколько там интересного.

[impostor] Усталось и как с ней справиться - большой, но краткий обзор исследований на тему повышения работоспособности.
👍19
htop tips and tricks

> htop -d3 - можно уменьшить интервал обновления, например, до 300мс.

t - включить tree view (при этом сортировка по CPU отключается), с возможностью collapse/expand ветвей курсором.

z - приостановить обновление, полезно, если хочется рассмотреть список процессов подробнее, а он "дергается".

F - follow a process, т.е. выбрать конкретный, чтобы не потерять его при перестроениях списка.

a - установить thread affinity выбранному процессу.

s - посмотреть strace выбранного процесса.

l - отобразить открытые файлы процесса (lsof).

space - выделение процессов, U - отменить выделение, F9 - отправить процессу сигнал.
👍14🔥53
Интересный телеграм канал про разработку и HFT: On the way to 10x engineering. Стартовал примерно в одно время с моим каналом. Кто пишет и из какой компании - неизвестно, но пишет хорошо. Например:
- Speculative trading
- Знакомство с FPGA
- Hard skills in HFT
👍6
Анонсирую воркшоп "C++ concurrency: condition_variable". Я проводил его на C++ Russia 2024, и тогда было собрано 50 человек, и отзывы были положительные. Теперь собираю участников самостоятельно. Воркшоп пройдёт онлайн в пятницу 12 июля в 19:00 (utc+3), приходите!

Что будет на воркшопе:
- 6 практических задач
- напишете несколько примитивов синхронизации (Latch, Queue, RWLock, call_once, future/promise) на основе CV
- даётся код и нужно дописать реализацию класса или починить баг, всё максимально удобно для работы
- есть дополнительные усложнения для шустрых
- поговорим о том, что такое и когда нужен CV
- обсудим типовые ошибки и как их починить
- будет всё, что могут спросить на собесе на эту тему

Что будет после воркшопа:
- 2-3 задачи на самостоятельную проработку в свободное время

Когда: пятница 12 июля в 19:00 (utc+3)
Стоимость: свободная цена, т.е. выбираете сами от 0 руб до вы оплачиваете мне квартиру.

Зарегистрироваться (опционально)
Добавить в календарь
👍20
Про технические моменты по воркшопу:

1) Сервис видео конференций. Нужна поддержка конфы до 3ч, из-за чего не подходят бесплатные версии сервисов. Нужна задержка менее 300мс, из-за чего не подходят Youtube Live (в ultra low latency режиме обещают <5 сек, но это всё еще многовато), и Twitch (10-15 sec). Нужна оплата для пользователей РФ, из-за чего отваливается Google Meet. Cisco Webex в целом недоступна для нас. Microsoft Teams чересчур кроваво-корпоративный и мудрёный. Остаётся Zoom за $15 в месяц, его и взял.

2) Микрофон. Взял конденсаторный Fifine A6V с подключением по USB Type-C. Проверим в деле в пятницу.

3) Для ноутбука взял USB hub, чтобы позволить одновременно зарядку по USB Type-C и микрофон.

4) Видео камера: встроенная в ноутбук. Освещение: как получится в переговорке. Есть желание сделать качественную картинку, но это когда-нибудь в будущем. Сейчас сосредоточусь на содержимом.

5) Сервис для оплаты: крипта, либо по колхозному перевод на банк. карту. Думал, подключить Tribute, но в следующий раз. Оплата опциональна (свободная цена).

6) Код: в GitHub репозитории, будет открыт за несколько часов до начала, чтобы вы могли склонировать и собрать заранее. Сборка: любым удобным вам компилятором, поддерживающим C++17, плюс cmake. IDE: любое удобное вам.

7) Обратная связь. Стандартно соберу через Google Forms после мероприятия.

upd: Fifine микрофон по звуку норм (за свои деньги), но у него плохой usb-c порт, отваливается.
👍65
Всем спасибо за участие! Этот тред для участников воркшопа. В комментарии к этому посту скину все ссылки.
🔥9
Что я понял про ведение практических вебинаров (воркшопов)?

Я провёл одну тему (condition variables) три раза с разными людьми, и вот что понял:
— практико-ориентированный подход, в котором участники пишут код прямо сейчас, востребован. Лекций, вебинаров и курсов много, а воркшопов мало.

— 3 часа это слишком, надо уклываться в 2:15 - 2:30, и делать один перерыв на 2-3 минуты (достаточно, чтобы сходить в туалет или налить чаю).

— идея с усложнениями - работает, и некоторые успевают их выполнять.

— Zoom хорошо подходит для такого формата (и, пожалуй, только он и подходит), имеет доступную цену.

— не все задачи и темы подходят для такого формата, т.к. некоторые темы нужно обдумывать и практиковать часами, если не днями. Такое лучше оставлять на offline.

— сначала у меня было 7 задач, потом я сделал 6 задач, сейчас считаю, что достаточно где-то 4-5 задач.

— со своего канала на ~300 человек без какой-либо рекламы у меня получилось привлечь ~20 участников, на конференции было 50 участников и было бы больше, но мы ограничили сверху. Если бы я постарался больше, то смог бы сам привлечь 25-30. С рекламой, полагаю, реально было бы достичь и 60-80, но доказательств пока нет. Учтите, что вход был бесплатным, а с платным входом понадобится реклама и мощная подача.

— до конца у меня доходят примерно 50-60% участников. Надо стремиться увеличивать этот процент.

— я получил 3000 тыр со свободной цены (спасибо, Денис). Добровольная оплата - это хороший признак либо получения реальной пользы, либо эмоций. Однако ради денег делать это не получится, это всё же для каких-то других целей: получить признание, внимание, подписчиков, реализовать себя и т.п.

Дальнейшие планы:
— разработать следующий воркшоп на новую тему на август

— подумать, возможно ли сделать это не в live, чтобы больше людей могли решать задачи в свободное время
🔥16👍2
В пятницу возник интересный вопрос:
template <typename T>
class Queue {
public:
void push(const T& val) {
std::unique_lock l{_m};
_queue.push(val);
if (_queue.size() == 1) { // was empty
_not_empty_cv.notify_one();
}
}

T pop() {
std::unique_lock l{_m};
_not_empty_cv.wait(l, [&]() {
return !_queue.empty();
});
auto v = std::move(_queue.front());
_queue.pop();
return v;
}

private:
std::mutex _m;
std::condition_variable _not_empty_cv;
std::queue<T> _queue;
};

Есть ли здесь проблема?
🤔3🔥2
В комментах к предыдущему вопросу были верные ответы. Продолжаем ковырять condition variables, есть ли здесь проблема?

template <typename T>
class Queue {
public:
Queue(size_t limit): _limit(limit) {}

void push(const T& val) {
std::unique_lock l{_m};
_cv.wait(l, [&] { return !_limit || _queue.size() < _limit; });
_queue.push(val);
_cv.notify_one(); // there's at least one item!
}

T pop() {
std::unique_lock l{_m};
_cv.wait(l, [&] { return !_queue.empty(); });
auto v = std::move(_queue.front());
_queue.pop();
_cv.notify_one(); // there's at least one slot!
return v;
}

private:
std::mutex _m;
std::condition_variable _cv;
std::queue<T> _queue;

size_t _limit;
};
Третьим будет вопрос: как лучше и как корректно: делать unlock после notify или до (и почему)?
{
std::unique_lock l{_m};
_queue.push(val);
_cv.notify_one();
}

или
{
std::unique_lock l{_m};
_queue.push(val);
}
_cv.notify_one();
👍2
Про логирование и как его ускорить

Как-то раз я ускорял логгер через io_uring, т.к. скорость логгера не позволяла совмещать активную торговлю и достаточное количество информации для расследования случившихся инцидентов. Поэтому расскажу что понял на эту тему. Простое логирование состоит из 2х частей: форматирование и вывод. Различные throttle'ры, примочки, фильтры, окрашиватели рассматривать не будем.

Форматирование:
1) std::stringstream - не стоит, не надо: это медленно.
2) std::snprintf - не стоит, не надо: медленно, не современно.
3) std::format, поддерживается только с C++20. Я его не смотрел, но подозреваю, что в текущем виде libfmt будет быстрее.
4) libfmt - базовый выбор, достаточно быстрый. Для самых критических областей добавляем FMT_COMPILE, но не повсюду.
5) Не форматировать вообще. Можно складывать бинарные данные в файл (подход Binlog), либо отправлять куда-то (но это получается уже телеметрия). Но тогда файл требует декодирования отдельной тулзой. Но это можно автоматизировать.
6) Выносить форматирование в отдельный поток. Интересный подход из Quill. Они encode'ят аргументы в буфер, и предполагается, что это быстрее, чем отформатировать. Попробую эту либу, и позже поделюсь впечатлениями.
7) Еще крайне желательно не вычислять формат аргументы, если текущий verbosity все равно не выведет эту строку. Это приводит нас к тому, что нам подходят только макросы в том месте, где юзеры вызывают логирование.

Какие есть варианты по выводу сформированной строки на file storage:
1) Вывод в файл через:
- std::ofstream::operator << и flush
- fwrite + fflush (glibc)
- один write syscall

Выдают примерно одинаковые величины задержек. По логике можно представить, что дёрнуть просто syscall дешевле, но по факту разницу сложно увидеть.

В первых двух вариантах можно не делать flush на каждую строку, это сильно быстрее (т.к. данные буферятся в юзерспейсе), но тогда:
- Если долго нет новой строчки, то последнюю можно долго не видеть в логе. Но можно дополнительно flush'ить по таймеру.
- Что-то потеряется при креше, т.к. останется в памяти процесса. Однако это можно достать из кордампа gdb-скриптюней (такое не писал, но выглядит осуществимым).

Проблемы: средняя скорость min/avg: до 1 микроса, но периодически write может сделать серьезный пик, уходя в запись на устройство на 1-5мс (это на nvme). Можно попробовать понастраивать механизм сбрасывания dirty pages (см. sysctl -a | grep vm.dirty_).

2) Передаём задачу записи в отдельный поток. Так делает, например, Quill. Это очень быстро (скорость: от сотни наносекунд, если используете простую очередь, mutex и cv, и несколько наносекунд, если пишете в ring buffer (если не боитесь переполнения и нет параллельных вызовов)), но имеет свои недостатки:
- Этому отдельному потоку тоже нужно какое-то (неторговое) ядро.
- При креше вы можете потерять несколько последних строк (а именно они обычно нужны при креше). Снова можно пробовать выковыривать из крешдампа, но это неудобно. Скорее всего, можно дождаться дозаписи в крэшхэндлере.

3) Запись в ядре через io_uring: выглядит интересно, но имеет свои сложности: код надо очень аккуратно писать, понимать как настраивать kworker'ы (куда их пиннить, какие там размеры буферов и т.п.). Подходит для kernel'ов старше 5.1. В случае креша без специальных приседаний ядро не дозапишет строки. Я эту штуку использовал, и было интересно познакомиться с механизмом. Ждал дозаписи строк в крэш-хэндлере.

4) Запись в отдельном своём сервисе. Как ему максимально быстро передать строку - отдельный непростой вопрос, который может сильно всё усложнить. Сервисом тоже нужно управлять, деплоить, он тоже может упасть.

5) Вариант предыдущего пункта: выводить в stdout и писать в файловую систему через стандартный сервис (journald, dockerd). Тоже один syscall, поэтому по скорости как запись в файл, но без пиков в несколько миллисов. Довольно быстро, стандартно. Легко поддержать ротацию. Если процесс крашнется сразу после лог строчки, то демон всё дозапишет.

Дополняйте, если что, или поправьте.
🔥13👍1🫡1
Про ИИ на собесах

Хотя это всё еще редкость, но всё же появляются люди, которые пользуются ИИ (Chat GPT и аналоги) во время собеседований для получения преимуществ. Подавляющее большинство собесов сейчас проводятся дистанционно, и организовать это несложно. Один раз и нам такой чел попался (хотя доказательств нет). Но как с этим бороться? У меня нет хороших решений, но вот несколько средне-всратых идей:

1) Спрашивать сложные и редкие вопросы, на которые Chat GPT не знает ответ? Однако есть сомнение, что и кандидат обязан знать ответ на такой специфичный вопрос.

2) Спрашивать вопрос, на который Chat GPT знает ответ, а нормальный кандидат не должен знать ответа.

3) Проводить серию вопросов, требующих коротких ответов (и предупредить, что ответы должны быть короткие). Мысль в том, что ИИ склонен выдавать очень длинные ответы.

4) Смотреть, как кандидат пишет программу. Делает ли мелкие ошибки? Улучшает ли программу постепенно? Корявое ли у него форматирование? Прогоняет ли тестовые данные в уме? Если да, то он нормальный.

5) Внимательно смотреть на глаза, читает ли собеседник с экрана при ответе на вопросы? Всегда просить включать камеру (и предупреждать об этом до старта собеса).

6) Звать на финальный технический собес в офис, заодно можно будет лично познакомиться, и офис показать.

7) Увольнять с испытательного срока, если не справляется с задачами.

А к вам приходили AI-cheating энтузиасты? Нужно ли с этим бороться? А вы сами пробовали так читерить?
👍8
Alber Blanc, где я работаю, активно нанимает, и у нас несколько вкусных вакансий.

Например:
C++ developer (Core team), core классы и сервисы, инфраструктура для быстрой торговли, обработка и пересылка маркет даты, оптимизация, взаимодействие с FPGA и т.п.
C++ developer (Gates team), коннекторы к биржам, оптимизация сетевых подключений, работа с маркет датой, метрики и т.п.
Network/SRE engineer, работа с различными сетями, тюнинг линукса, отлаживание проблем ОС, автоматизация сетевых задач, работа с AWS, хостами, инфра сервисами.

Нанимаем на Кипр (Лимассол), но есть офисы и в других локациях.

Особенности:
— Нет bullshit практик и траты времени, мало бюрократии, доступы выдаются быстро.

— Топы открыты, доступны, и работают наравне с нами (программируют, например), плоская структура компании.

— По оплате HFT сфера, пожалуй, самая привлекательная: приятная ЗП, полугодовые бонусы по результатам работы, оплата дежурств, если участвуешь.

— Четкие критерии успешности, быстрый результат от твоей работы.

— Работа в офисе, удалёнки нет. Не всем это подходит, но мне вполне.

— Мало документации, кое-где не хватает комментариев и читаемости/вылизанности кода.

Вы можете податься самостоятельно, а можете через меня: я посмотрю ваше резюме, дам базовые советы, если нужно, и сделаю вам рефку. Потом, если проходите, то я получаю бонус. Чего я не делаю: не рассказываю, что конкретно спрашивают на собесе (только в общих словах).

Советую не пропускать такую возможность.

Полный список тут (нужны также кванты, трейды, QA, аналитики, фронтендеры)
👍16🔥3👏21
Наверное, уже все заметили: красный цвет на всех рынках. Свечи вниз, другими словами. Слив. Дамп. Крипта приняла на себя первый удар, т.к. классические фондовые биржи закрыты в выходные. Краткосрочного резкого падения рынка HFT'шники не боятся, они этого ждут: деньги зарабатываются на движениях в любую сторону. Однако, торговая инфра переходит в такое время в режим повышенной нагрузки (опасности):
- Повышенный трафик с рынка, выжирается RAM, CPU в сотку, сервисы могут начать не вывозить, очереди наполняются и переливаются, начинают тормозить сопутствующие сервисы, и т.п.
- Вы хотите много наторговать, и выжираете API rate limits.
- Логи сыпятся так быстро, что не успеваешь вычитывать. Разбираешь несколько уже часов после движения.
- API бирж начинает присылать новые виды ошибок/ответов/состояний, на которые, возможно, вы не рассчитывали.
- События с биржи могут начать вести себя непредсказумо: молчать некоторое время, иметь увеличивенные задержки, идти в другом порядке и т.п.
- Из-за большого количества событий повышаются шансы нароллить маловероятные события: спящие баги, коллизии, переполнения, совпадение событий по времени и неожиданные реордеры.
👍29🔥1