Про логирование и как его ускорить
Как-то раз я ускорял логгер через io_uring, т.к. скорость логгера не позволяла совмещать активную торговлю и достаточное количество информации для расследования случившихся инцидентов. Поэтому расскажу что понял на эту тему. Простое логирование состоит из 2х частей: форматирование и вывод. Различные throttle'ры, примочки, фильтры, окрашиватели рассматривать не будем.
Форматирование:
1)
2)
3)
4)
5) Не форматировать вообще. Можно складывать бинарные данные в файл (подход Binlog), либо отправлять куда-то (но это получается уже телеметрия). Но тогда файл требует декодирования отдельной тулзой. Но это можно автоматизировать.
6) Выносить форматирование в отдельный поток. Интересный подход из Quill. Они encode'ят аргументы в буфер, и предполагается, что это быстрее, чем отформатировать. Попробую эту либу, и позже поделюсь впечатлениями.
7) Еще крайне желательно не вычислять формат аргументы, если текущий verbosity все равно не выведет эту строку. Это приводит нас к тому, что нам подходят только макросы в том месте, где юзеры вызывают логирование.
Какие есть варианты по выводу сформированной строки на file storage:
1) Вывод в файл через:
-
-
- один
Выдают примерно одинаковые величины задержек. По логике можно представить, что дёрнуть просто syscall дешевле, но по факту разницу сложно увидеть.
В первых двух вариантах можно не делать flush на каждую строку, это сильно быстрее (т.к. данные буферятся в юзерспейсе), но тогда:
- Если долго нет новой строчки, то последнюю можно долго не видеть в логе. Но можно дополнительно flush'ить по таймеру.
- Что-то потеряется при креше, т.к. останется в памяти процесса. Однако это можно достать из кордампа gdb-скриптюней (такое не писал, но выглядит осуществимым).
Проблемы: средняя скорость min/avg: до 1 микроса, но периодически
2) Передаём задачу записи в отдельный поток. Так делает, например, Quill. Это очень быстро (скорость: от сотни наносекунд, если используете простую очередь, mutex и cv, и несколько наносекунд, если пишете в ring buffer (если не боитесь переполнения и нет параллельных вызовов)), но имеет свои недостатки:
- Этому отдельному потоку тоже нужно какое-то (неторговое) ядро.
- При креше вы можете потерять несколько последних строк (а именно они обычно нужны при креше). Снова можно пробовать выковыривать из крешдампа, но это неудобно. Скорее всего, можно дождаться дозаписи в крэшхэндлере.
3) Запись в ядре через
4) Запись в отдельном своём сервисе. Как ему максимально быстро передать строку - отдельный непростой вопрос, который может сильно всё усложнить. Сервисом тоже нужно управлять, деплоить, он тоже может упасть.
5) Вариант предыдущего пункта: выводить в stdout и писать в файловую систему через стандартный сервис (journald, dockerd). Тоже один syscall, поэтому по скорости как запись в файл, но без пиков в несколько миллисов. Довольно быстро, стандартно. Легко поддержать ротацию. Если процесс крашнется сразу после лог строчки, то демон всё дозапишет.
Дополняйте, если что, или поправьте.
Как-то раз я ускорял логгер через 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, поэтому по скорости как запись в файл, но без пиков в несколько миллисов. Довольно быстро, стандартно. Легко поддержать ротацию. Если процесс крашнется сразу после лог строчки, то демон всё дозапишет.
Дополняйте, если что, или поправьте.
Про ИИ на собесах
Хотя это всё еще редкость, но всё же появляются люди, которые пользуются ИИ (Chat GPT и аналоги) во время собеседований для получения преимуществ. Подавляющее большинство собесов сейчас проводятся дистанционно, и организовать это несложно. Один раз и нам такой чел попался (хотя доказательств нет). Но как с этим бороться? У меня нет хороших решений, но вот несколько средне-всратых идей:
1) Спрашивать сложные и редкие вопросы, на которые Chat GPT не знает ответ? Однако есть сомнение, что и кандидат обязан знать ответ на такой специфичный вопрос.
2) Спрашивать вопрос, на который Chat GPT знает ответ, а нормальный кандидат не должен знать ответа.
3) Проводить серию вопросов, требующих коротких ответов (и предупредить, что ответы должны быть короткие). Мысль в том, что ИИ склонен выдавать очень длинные ответы.
4) Смотреть, как кандидат пишет программу. Делает ли мелкие ошибки? Улучшает ли программу постепенно? Корявое ли у него форматирование? Прогоняет ли тестовые данные в уме? Если да, то он нормальный.
5) Внимательно смотреть на глаза, читает ли собеседник с экрана при ответе на вопросы? Всегда просить включать камеру (и предупреждать об этом до старта собеса).
6) Звать на финальный технический собес в офис, заодно можно будет лично познакомиться, и офис показать.
7) Увольнять с испытательного срока, если не справляется с задачами.
А к вам приходили AI-cheating энтузиасты? Нужно ли с этим бороться? А вы сами пробовали так читерить?
Хотя это всё еще редкость, но всё же появляются люди, которые пользуются ИИ (Chat GPT и аналоги) во время собеседований для получения преимуществ. Подавляющее большинство собесов сейчас проводятся дистанционно, и организовать это несложно. Один раз и нам такой чел попался (хотя доказательств нет). Но как с этим бороться? У меня нет хороших решений, но вот несколько средне-всратых идей:
1) Спрашивать сложные и редкие вопросы, на которые Chat GPT не знает ответ? Однако есть сомнение, что и кандидат обязан знать ответ на такой специфичный вопрос.
2) Спрашивать вопрос, на который Chat GPT знает ответ, а нормальный кандидат не должен знать ответа.
3) Проводить серию вопросов, требующих коротких ответов (и предупредить, что ответы должны быть короткие). Мысль в том, что ИИ склонен выдавать очень длинные ответы.
4) Смотреть, как кандидат пишет программу. Делает ли мелкие ошибки? Улучшает ли программу постепенно? Корявое ли у него форматирование? Прогоняет ли тестовые данные в уме? Если да, то он нормальный.
5) Внимательно смотреть на глаза, читает ли собеседник с экрана при ответе на вопросы? Всегда просить включать камеру (и предупреждать об этом до старта собеса).
6) Звать на финальный технический собес в офис, заодно можно будет лично познакомиться, и офис показать.
7) Увольнять с испытательного срока, если не справляется с задачами.
А к вам приходили AI-cheating энтузиасты? Нужно ли с этим бороться? А вы сами пробовали так читерить?
Alber Blanc, где я работаю, активно нанимает, и у нас несколько вкусных вакансий.
Например:
— C++ developer (Core team), core классы и сервисы, инфраструктура для быстрой торговли, обработка и пересылка маркет даты, оптимизация, взаимодействие с FPGA и т.п.
— C++ developer (Gates team), коннекторы к биржам, оптимизация сетевых подключений, работа с маркет датой, метрики и т.п.
— Network/SRE engineer, работа с различными сетями, тюнинг линукса, отлаживание проблем ОС, автоматизация сетевых задач, работа с AWS, хостами, инфра сервисами.
Нанимаем на Кипр (Лимассол), но есть офисы и в других локациях.
Особенности:
— Нет bullshit практик и траты времени, мало бюрократии, доступы выдаются быстро.
— Топы открыты, доступны, и работают наравне с нами (программируют, например), плоская структура компании.
— По оплате HFT сфера, пожалуй, самая привлекательная: приятная ЗП, полугодовые бонусы по результатам работы, оплата дежурств, если участвуешь.
— Четкие критерии успешности, быстрый результат от твоей работы.
— Работа в офисе, удалёнки нет. Не всем это подходит, но мне вполне.
— Мало документации, кое-где не хватает комментариев и читаемости/вылизанности кода.
Вы можете податься самостоятельно, а можете через меня: я посмотрю ваше резюме, дам базовые советы, если нужно, и сделаю вам рефку. Потом, если проходите, то я получаю бонус. Чего я не делаю: не рассказываю, что конкретно спрашивают на собесе (только в общих словах).
Советую не пропускать такую возможность.
Полный список тут (нужны также кванты, трейды, QA, аналитики, фронтендеры)
Например:
— C++ developer (Core team), core классы и сервисы, инфраструктура для быстрой торговли, обработка и пересылка маркет даты, оптимизация, взаимодействие с FPGA и т.п.
— C++ developer (Gates team), коннекторы к биржам, оптимизация сетевых подключений, работа с маркет датой, метрики и т.п.
— Network/SRE engineer, работа с различными сетями, тюнинг линукса, отлаживание проблем ОС, автоматизация сетевых задач, работа с AWS, хостами, инфра сервисами.
Нанимаем на Кипр (Лимассол), но есть офисы и в других локациях.
Особенности:
— Нет bullshit практик и траты времени, мало бюрократии, доступы выдаются быстро.
— Топы открыты, доступны, и работают наравне с нами (программируют, например), плоская структура компании.
— По оплате HFT сфера, пожалуй, самая привлекательная: приятная ЗП, полугодовые бонусы по результатам работы, оплата дежурств, если участвуешь.
— Четкие критерии успешности, быстрый результат от твоей работы.
— Работа в офисе, удалёнки нет. Не всем это подходит, но мне вполне.
— Мало документации, кое-где не хватает комментариев и читаемости/вылизанности кода.
Вы можете податься самостоятельно, а можете через меня: я посмотрю ваше резюме, дам базовые советы, если нужно, и сделаю вам рефку. Потом, если проходите, то я получаю бонус. Чего я не делаю: не рассказываю, что конкретно спрашивают на собесе (только в общих словах).
Советую не пропускать такую возможность.
Полный список тут (нужны также кванты, трейды, QA, аналитики, фронтендеры)
Alberblanc
C++ Developer (Core)
We are looking for talented and experienced software engineers to develop, optimize, and support our systems and tools. And we have variety of roles for C++ developers.
Наверное, уже все заметили: красный цвет на всех рынках. Свечи вниз, другими словами. Слив. Дамп. Крипта приняла на себя первый удар, т.к. классические фондовые биржи закрыты в выходные. Краткосрочного резкого падения рынка HFT'шники не боятся, они этого ждут: деньги зарабатываются на движениях в любую сторону. Однако, торговая инфра переходит в такое время в режим повышенной нагрузки (опасности):
- Повышенный трафик с рынка, выжирается RAM, CPU в сотку, сервисы могут начать не вывозить, очереди наполняются и переливаются, начинают тормозить сопутствующие сервисы, и т.п.
- Вы хотите много наторговать, и выжираете API rate limits.
- Логи сыпятся так быстро, что не успеваешь вычитывать. Разбираешь несколько уже часов после движения.
- API бирж начинает присылать новые виды ошибок/ответов/состояний, на которые, возможно, вы не рассчитывали.
- События с биржи могут начать вести себя непредсказумо: молчать некоторое время, иметь увеличивенные задержки, идти в другом порядке и т.п.
- Из-за большого количества событий повышаются шансы нароллить маловероятные события: спящие баги, коллизии, переполнения, совпадение событий по времени и неожиданные реордеры.
- Повышенный трафик с рынка, выжирается RAM, CPU в сотку, сервисы могут начать не вывозить, очереди наполняются и переливаются, начинают тормозить сопутствующие сервисы, и т.п.
- Вы хотите много наторговать, и выжираете API rate limits.
- Логи сыпятся так быстро, что не успеваешь вычитывать. Разбираешь несколько уже часов после движения.
- API бирж начинает присылать новые виды ошибок/ответов/состояний, на которые, возможно, вы не рассчитывали.
- События с биржи могут начать вести себя непредсказумо: молчать некоторое время, иметь увеличивенные задержки, идти в другом порядке и т.п.
- Из-за большого количества событий повышаются шансы нароллить маловероятные события: спящие баги, коллизии, переполнения, совпадение событий по времени и неожиданные реордеры.
На работе завал, придётся делегировать.
Что стоит почитать по C++? (новые статьи, заметки, новости, блогпосты, видео)
Что стоит почитать по C++? (новые статьи, заметки, новости, блогпосты, видео)
This media is not supported in your browser
VIEW IN TELEGRAM
Обнаружил, что Алиса теперь использует YandexGPT для ответа на несценарные вопросы. Пока ещё не придумал, как это использовать, но вот вам Алиса, пишущая на плюсах
Что я понял про ведение телеграм канала (с января 2024)
- Можно ссылку на свой канал положить в свой профиль. Смотри пример: @yukigaru.
- Очень хорошо для меня сработала публикация в Linkedin, она принесла несколько десятков новых подписчиков. Чувствую, что в этом способе привлечения для меня еще есть большой потенциал. Взаимопиар похожих каналов работает, но мне принесло умеренно (до 20, насколько помню, у "on the way to 10x engineer"). Платная реклама в инфо-канале @seniorcpp принесла мне очень мало, это того не стоило, но попробовать хотелось.
- Если вы премиум юзер, то вы можете оставлять комментарии в чужих каналах от имени своего канала.
- Простые комментарии в чужих каналах дают мне примерно +1 подписчик на комментарий. Качественные расписанные комментарии могут дать больше, но я не уделяю этому время.
- Однако некоторые каналы заранее запрещают писать от имени своего канала (в них просто нельзя выбрать свой канал). Существуют так же боты, удаляющие комментарии от чужих каналов.
- Легко отличить какой канал создан для души, а какой чисто ради заработка. Вторые пишут общую якобы полезную информацию, но по факту инфо-мусор. Используют chat gpt для контента, содержат ошибки, но при этом имеют в десять раз больше подписчиков. Доказательств нет, но возможно, что часть подписчиков - это боты, и нужны для повышения цен на рекламу.
- Развить свой блог всё еще можно, и даже без вложений. Пробуйте, если вам интересно! Если вы начинающий, то могу написать о вас. Да, у меня пока аудитория небольшая, но если у вас до 50 человек, то это имеет смысл.
- По наблюдениям, высоко востребовано высоко-профессиональное уникальное чтиво, где автор показывает мастерство, и чего нигде больше не найдешь, и хорошо заходят подборки с полезными материалами.
- Я не зарабатываю на канале, и пока не планирую. Если бы начал монетизацию, вам бы полилась реклама курсов, а мне этого не хочется.
- У меня много идей, о чем я могу написать, но не хватает времени на реализацию.
Чего я не понял, но хотел бы понять:
- Я вижу статистику по постам, например, пост со ссылками на интересные мне материалы (https://www.tgoop.com/hft_dev/49) расшарили 27 раз и в это число не входит "Saved messages". Спасибо, что делитесь постами! Но все же, кто и куда forward'ит мои посты?
- Можно ссылку на свой канал положить в свой профиль. Смотри пример: @yukigaru.
- Очень хорошо для меня сработала публикация в Linkedin, она принесла несколько десятков новых подписчиков. Чувствую, что в этом способе привлечения для меня еще есть большой потенциал. Взаимопиар похожих каналов работает, но мне принесло умеренно (до 20, насколько помню, у "on the way to 10x engineer"). Платная реклама в инфо-канале @seniorcpp принесла мне очень мало, это того не стоило, но попробовать хотелось.
- Если вы премиум юзер, то вы можете оставлять комментарии в чужих каналах от имени своего канала.
- Простые комментарии в чужих каналах дают мне примерно +1 подписчик на комментарий. Качественные расписанные комментарии могут дать больше, но я не уделяю этому время.
- Однако некоторые каналы заранее запрещают писать от имени своего канала (в них просто нельзя выбрать свой канал). Существуют так же боты, удаляющие комментарии от чужих каналов.
- Легко отличить какой канал создан для души, а какой чисто ради заработка. Вторые пишут общую якобы полезную информацию, но по факту инфо-мусор. Используют chat gpt для контента, содержат ошибки, но при этом имеют в десять раз больше подписчиков. Доказательств нет, но возможно, что часть подписчиков - это боты, и нужны для повышения цен на рекламу.
- Развить свой блог всё еще можно, и даже без вложений. Пробуйте, если вам интересно! Если вы начинающий, то могу написать о вас. Да, у меня пока аудитория небольшая, но если у вас до 50 человек, то это имеет смысл.
- По наблюдениям, высоко востребовано высоко-профессиональное уникальное чтиво, где автор показывает мастерство, и чего нигде больше не найдешь, и хорошо заходят подборки с полезными материалами.
- Я не зарабатываю на канале, и пока не планирую. Если бы начал монетизацию, вам бы полилась реклама курсов, а мне этого не хочется.
- У меня много идей, о чем я могу написать, но не хватает времени на реализацию.
Чего я не понял, но хотел бы понять:
- Я вижу статистику по постам, например, пост со ссылками на интересные мне материалы (https://www.tgoop.com/hft_dev/49) расшарили 27 раз и в это число не входит "Saved messages". Спасибо, что делитесь постами! Но все же, кто и куда forward'ит мои посты?
Telegram
Один микросек - C++, low latency, concurrency, HFT
Что почитать по C++ и разработке в целом?
[easy] Comparison of the three implementations of std::string (MSVC, GCC, Clang), с погружением в то, как data(), size(), empty() обрабатывают два состояния (small/large string).
[easy] Какие ошибки есть в коде…
[easy] Comparison of the three implementations of std::string (MSVC, GCC, Clang), с погружением в то, как data(), size(), empty() обрабатывают два состояния (small/large string).
[easy] Какие ошибки есть в коде…
GDB позволяет вводить команды из файла
Приведу несколько примеров. Поставить breakpoint с условием:
Поставить одноразовый catch на write syscall:
Объявить функцию, которая принимает адрес и ставит условный watch на этот адрес:
Реальные сценарии как правило чуть сложнее, т.к. дебаг символов может и не быть, условия посложнее, но для демонстрации идеи эти подходят.
Далее команды можно запустить из файла:
или прямо в cli:
Да, то же самое можно ввести вручную поэтапно в cli, однако ручной ввод комманд требует времени, что может быть непозволительно в уже запущенных программах, которые нельзя прерывать.
GDB также умеет в Python скрипты, но на питоняке я писал только pretty-printer'ы. Кто-то использовал python в gdb?
Приведу несколько примеров. Поставить breakpoint с условием:
> cat 1.gdb
break my_func if (var > 10000)
commands
print var
info locals
info registers
backtrace
continue
end
Поставить одноразовый catch на write syscall:
tcatch syscall write
commands
printf "Syscall write\n"
printf "File descriptor: %d\n", $rdi
printf "Buffer: %p\n", $rsi
printf "Bytes: %d\n", $rdx
continue
end
Объявить функцию, которая принимает адрес и ставит условный watch на этот адрес:
define my_int_watch
watch *(int*)$arg0 if *(int*)$arg0 % 3 == 0
commands
printf "New value: %d\n", *(int*)$arg0
continue
end
end
Реальные сценарии как правило чуть сложнее, т.к. дебаг символов может и не быть, условия посложнее, но для демонстрации идеи эти подходят.
Далее команды можно запустить из файла:
gdb -p 1234 -x 1.gdb
или прямо в cli:
> source 1.gdb
Да, то же самое можно ввести вручную поэтапно в cli, однако ручной ввод комманд требует времени, что может быть непозволительно в уже запущенных программах, которые нельзя прерывать.
GDB также умеет в Python скрипты, но на питоняке я писал только pretty-printer'ы. Кто-то использовал python в gdb?
Если подумать, каких провалов я опасаюсь в работе, то это такой тип сбоев, в которых ваша торговая система набирает очень большую и нежелательную позицию. Она начинает неконтролируемо и быстро слать ордера на биржу, превышая заложенные в систему величины рисков. Такое произошло с Knight Capital (в блоге и на хабре на русском), что впоследствии привело к продаже фирмы. Всё произойдет за минуты или секунды, и уже после случившегося вы будете какое-то время только осознавать "эээ а что происходит". Либо, как вариант, баг в логике, неверные подсчёты или парсинг ответов приводит к тому, что подсчитанная позиция расходится с реальной. Вы думаете, у вас лонг на 100k, а у вас шорт на 100k, и рынок, зараза, идет вверх. Подобное случалось и со мной и с коллегами.
Второй неприятный тип сбоев: когда из-за бага торговая система простаивает. Представьте, что ваша, с любовью разработанная, фича остановила весь терминал, и фирма не зарабатывает, скажем, 5k в минуту, во всех рабочих чатах пишут ваше имя (а вы в отпуске). Понятно, что такая ситуация есть в других IT сферах, Crowdstrike подтвердит.
Третим в списке поставлю утечку приватных ключей и паролей (в результате небрежности или злого умысла сотрудников или внешней атаки). Вот вам любопытный случай c 3commas.
Предлагаю порассуждать, какие бы вы ввели механизмы, практики, правила в своем стартапе для защиты от подобных провалов? А точно хватит времени на это (в стартапе)? А точно не будет багов в самих механизмах защиты (если речь о коде)?
Второй неприятный тип сбоев: когда из-за бага торговая система простаивает. Представьте, что ваша, с любовью разработанная, фича остановила весь терминал, и фирма не зарабатывает, скажем, 5k в минуту, во всех рабочих чатах пишут ваше имя (а вы в отпуске). Понятно, что такая ситуация есть в других IT сферах, Crowdstrike подтвердит.
Третим в списке поставлю утечку приватных ключей и паролей (в результате небрежности или злого умысла сотрудников или внешней атаки). Вот вам любопытный случай c 3commas.
Предлагаю порассуждать, какие бы вы ввели механизмы, практики, правила в своем стартапе для защиты от подобных провалов? А точно хватит времени на это (в стартапе)? А точно не будет багов в самих механизмах защиты (если речь о коде)?
Что почитать по C++?
https://www.saminiir.com/lets-code-tcp-ip-stack-1-ethernet-arp/ - серия статей "Let's code a TCP/IP stack"
https://pthorpe92.dev/programming/systems/common-misunderstandings/ - серия статей "Common misunderstandings" по processes, tasks, async I/O.
https://eli.thegreenplace.net/2017/concurrent-servers-part-1-introduction/ - базовое "Concurrent servers" про select/epoll.
https://accu.org/journals/overload/32/182/teodorescu/ - базовый гайд про атомики "In an atomic world" от accu.
https://www.think-cell.com/en/career/devblog/cpp-needs-undefined-behavior-but-maybe-less - про UB и будущий erroneous behavior.
https://lemire.me/blog/2024/09/09/replace-stdstring-by-stdstring_view-when-you-can/ - один mega-string вместо кучи мелких от Daniel Lemire.
https://habr.com/ru/companies/pvs-studio/articles/846532/ - std::array не медленнее C-массива от PVS studio.
https://www.studyplan.dev/pro-cpp/concepts - серия доступных уроков по C++20 concepts, если еще не вкатились.
https://www.saminiir.com/lets-code-tcp-ip-stack-1-ethernet-arp/ - серия статей "Let's code a TCP/IP stack"
https://pthorpe92.dev/programming/systems/common-misunderstandings/ - серия статей "Common misunderstandings" по processes, tasks, async I/O.
https://eli.thegreenplace.net/2017/concurrent-servers-part-1-introduction/ - базовое "Concurrent servers" про select/epoll.
https://accu.org/journals/overload/32/182/teodorescu/ - базовый гайд про атомики "In an atomic world" от accu.
https://www.think-cell.com/en/career/devblog/cpp-needs-undefined-behavior-but-maybe-less - про UB и будущий erroneous behavior.
https://lemire.me/blog/2024/09/09/replace-stdstring-by-stdstring_view-when-you-can/ - один mega-string вместо кучи мелких от Daniel Lemire.
https://habr.com/ru/companies/pvs-studio/articles/846532/ - std::array не медленнее C-массива от PVS studio.
https://www.studyplan.dev/pro-cpp/concepts - серия доступных уроков по C++20 concepts, если еще не вкатились.
saminiir's hacker blog
Let's code a TCP/IP stack, 1: Ethernet & ARP
Writing your own TCP/IP stack may seem like a daunting task. Indeed, TCP has accumulated many specifications over its lifetime of more than thirty years. The core specification, however, is seemingly compact[^tcp-roadmap] - the important parts being TCP header…
Что мне нравится в API крипто бирж:
— наличие batch запросов (несколько запросов отправляется одной пачкой)
— таймстемпы в микросекундах, а лучше даже в наносекундах (у некоторых только в миллисекундах, а встречались даже секунды)
— несколько таймстемпов из различных этапов ордера (время приема, время матчинга, время отправки отчета)
— когда можно задать окно, позже которого биржа не примет моё сообщение
— наличие запросов: order info, get open orders, cancel all, kill switch on disconnect
— в ответе есть request id и тип запроса
— api ключи с гранулярным доступом
— доки не устаревшие и не содержат банальных ошибок (редкость)
Не нравится:
— когда json ответа слишком глубокий:
— когда ордербук передают через json объекты:
— когда различные рынки (spot/perps) одной биржи делают разные команды (и появляются различия в api)
— когда выкатывают обновления в субботу
— наличие batch запросов (несколько запросов отправляется одной пачкой)
— таймстемпы в микросекундах, а лучше даже в наносекундах (у некоторых только в миллисекундах, а встречались даже секунды)
— несколько таймстемпов из различных этапов ордера (время приема, время матчинга, время отправки отчета)
— когда можно задать окно, позже которого биржа не примет моё сообщение
— наличие запросов: order info, get open orders, cancel all, kill switch on disconnect
— в ответе есть request id и тип запроса
— api ключи с гранулярным доступом
— доки не устаревшие и не содержат банальных ошибок (редкость)
Не нравится:
— когда json ответа слишком глубокий:
{"channel":"post","data":{"id":167248,"response":{"type":"action","payload":{"status":"ok","response":{"type":"cancel","data":{"statuses":["success"]}}}}}}
— когда ордербук передают через json объекты:
"bids":[{"p":65332,"q":1.35},...]
, вместо массива массивов— когда различные рынки (spot/perps) одной биржи делают разные команды (и появляются различия в api)
— когда выкатывают обновления в субботу
Интересная статья 2014 года, в которой автор пытается увидеть манипуляции на рынке через визуализацию ордербука во времени. К сожалению, картинки сжатые, но понять можно (прищурившись). Для новичков будет интересна первая часть, где объясняется принципы устройства ордербука, а для бывалых - вторая.
Интересно, что это происходило 10 лет назад, а все перечисленные паттерны до сих можно увидеть в ордербуках.
https://parasec.net/blog/order-book-visualisation/
Интересно, что это происходило 10 лет назад, а все перечисленные паттерны до сих можно увидеть в ордербуках.
https://parasec.net/blog/order-book-visualisation/
Один криптобро решил сохранить свою seed фразу (12 слов по стандарту BIP-39) от кошелька на бумажке. Он схитрил и разделил последовательность посередине, записав первую часть на одну бумажкуу, оставшуюся - на другую, и спрятал их в разных местах.
К сожалению, злоумышленник нашел одну из бумажек, и теперь хочет перебрать недостающие 6 слов, чтобы забрать свой куш. Какое максимальное количество комбинаций ему может понадобиться перебирать?
hint #1:каждая позиция в фразе имеет 2048 возможных вариантов (слов), что составляет 11 бит энтропии
К сожалению, злоумышленник нашел одну из бумажек, и теперь хочет перебрать недостающие 6 слов, чтобы забрать свой куш. Какое максимальное количество комбинаций ему может понадобиться перебирать?
hint #1:
Решение задачи
Злоумышленник не знает, какую половинку он взял - левую или правую. По BIP-39 последние 4 бита последнего слова в фразе являются контрольной суммой. И контрольную сумму как вариант перебирать не нужно, её нужно вычислить. Поэтому мы должны рассмотреть две ветки:
- Если он нашел правую часть, тогда перебирать нужно левую часть. Каждое слово может быть одним из 2048 вариантов из специального словаря, или
- Если он нашел левую часть, то перебирать надо меньше, т.к. биты контрольной суммы перебирать не нужно. Из 66 бит энтропии (66 это 11 бит на слово x 6 слов) мы вычитаем 4 бита чексуммы, получаем 62, то есть
Т.к. ему нужно перебрать оба варианта, то суммируем числа, получаем
Злоумышленник не знает, какую половинку он взял - левую или правую. По BIP-39 последние 4 бита последнего слова в фразе являются контрольной суммой. И контрольную сумму как вариант перебирать не нужно, её нужно вычислить. Поэтому мы должны рассмотреть две ветки:
- Если он нашел правую часть, тогда перебирать нужно левую часть. Каждое слово может быть одним из 2048 вариантов из специального словаря, или
2^11
, а всего 6 слов, то есть 2^(11x6) = 2^66
.- Если он нашел левую часть, то перебирать надо меньше, т.к. биты контрольной суммы перебирать не нужно. Из 66 бит энтропии (66 это 11 бит на слово x 6 слов) мы вычитаем 4 бита чексуммы, получаем 62, то есть
2^62
варианта.Т.к. ему нужно перебрать оба варианта, то суммируем числа, получаем
2^66 + 2^62 = 2^62 x (2^4 + 1) = 2^62 x 17
или 78398662313265594368
.Что не так с float'ом и спасет ли double?
По каким таким причинам биржи не уважают floating-point numbers? Смотришь в документацию, а они в json'ах цену и количество лотов шлют не number type, а string type.
Не
Они так делают, если:
- практически: в их кодовой без используется какой-нибудь BigDecimal, который так сериализует числа.
- теоретически: они не могут гарантировать отсутствие чисел, непредставимых в double типе (например,
- для некоторых полей такую гарантию они могут дать, и тогда они используют uint64 (сравни поля ts и v).
- они заботятся о пользователе, вводя проблему в сознательную область (т.к. теперь просто as_float() в парсере не вызовешь) и снижая вероятность ошибки.
- упрощают пользователю возможность прокинуть строку в свой кастомный парсер (не часть json либы).
- оставляют себе микро-возможность вписать пустую строку, либо "Nan" или "Inf" (и такое бывало).
С точки зрения спецификации json тип Number не ограничен в размере и точности, но на практике юзерские либы же как-то должны с этим работать, поэтому на эту особенность спеки положиться нельзя.
Ладно, с биржами понятно. Допустим, прислали нам
Как будто бы может и хватить, но все же легко наступить на грабли:
- Операции не ассоциативны:
- Различные платформы могут давать различные результаты операций.
- Ошибки округления накапливаются при последовательных математических операциях (см. 0.1 + 0.2).
- Сравнивать два floating-point числа напрямую чревато.
- Что-то еще наверянка забыл, дополните, плз.
Практический пример: вы посылаете торговый ордер на quantity 0.3, вам приходит три сделки по 0.1. Вы их складываете, чтобы понять полностью ли заполнен ордер, и тут вы и приехали, ибо:
Да, вы можете сравнить числа через epsilon (
По итогу, используется либо double с дополнительными приседаниями (обвязками, проверками и т.п.), либо кастомный decimal тип (пример), либо изначально величины хранятся в самых мелких единицах (пример из Ethereum).
По каким таким причинам биржи не уважают floating-point numbers? Смотришь в документацию, а они в json'ах цену и количество лотов шлют не number type, а string type.
Не
{"price":36.12}
, а {"price":"36.12"}
.Они так делают, если:
- практически: в их кодовой без используется какой-нибудь BigDecimal, который так сериализует числа.
- теоретически: они не могут гарантировать отсутствие чисел, непредставимых в double типе (например,
9007199254740993.0
), даже, если сейчас такого не видно на горизонте. Проблема не в «маленьком диапазоне» double, а в невозможности точной двоичной репрезентации десятичных дробей.- для некоторых полей такую гарантию они могут дать, и тогда они используют uint64 (сравни поля ts и v).
- они заботятся о пользователе, вводя проблему в сознательную область (т.к. теперь просто as_float() в парсере не вызовешь) и снижая вероятность ошибки.
- упрощают пользователю возможность прокинуть строку в свой кастомный парсер (не часть json либы).
- оставляют себе микро-возможность вписать пустую строку, либо "Nan" или "Inf" (и такое бывало).
С точки зрения спецификации json тип Number не ограничен в размере и точности, но на практике юзерские либы же как-то должны с этим работать, поэтому на эту особенность спеки положиться нельзя.
Ладно, с биржами понятно. Допустим, прислали нам
"amount":"36.12"
. В чем ваш trading engine будет это хранить? Это фундаментальный вопрос для торговой системы. Ни ужели точности double не хватит, ведь он может показывать числа от 2.22507e-308 до 1.79769e+308, что уже довольно дофига?Как будто бы может и хватить, но все же легко наступить на грабли:
- Операции не ассоциативны:
(a + b) + c
может быть не равно a + (b + c)
.- Различные платформы могут давать различные результаты операций.
- Ошибки округления накапливаются при последовательных математических операциях (см. 0.1 + 0.2).
- Сравнивать два floating-point числа напрямую чревато.
- Что-то еще наверянка забыл, дополните, плз.
Практический пример: вы посылаете торговый ордер на quantity 0.3, вам приходит три сделки по 0.1. Вы их складываете, чтобы понять полностью ли заполнен ордер, и тут вы и приехали, ибо:
(0.1 + 0.1 + 0.1) == 0.3 вычисляется в false
Да, вы можете сравнить числа через epsilon (
abs(a-b) < eps
), но потенциально легко где-то забыть вызвать правильную функцию. Что тогда, вон из профессии?По итогу, используется либо double с дополнительными приседаниями (обвязками, проверками и т.п.), либо кастомный decimal тип (пример), либо изначально величины хранятся в самых мелких единицах (пример из Ethereum).
В декабре прошлого года я не продлил домен eyeleo.com для моего самого общественно-полезного проекта в жизни. Зашли посмотреть по ссылке? А зачем, домен то не продлён.
Где-то году в 2011-м в новогодние каникулы я написал Windows программу, напоминающую делать перерывы, чтобы глаза отдыхали от дисплея. Мне самому такая была нужна, а существующие вариации мне не нравились. EyeLeo была небольшой бесплатной программой, но делающей важное дело, поэтому она быстро стала весьма популярной, и долгое время я получал небольшой доход с донатов (через Adsense и Patreon). Однако из-за очень низкого качества кода и общей игрушечности, я буквально скрывал принадлежность к EyeLeo. Мне не хотелось, чтобы кто-то из коллег (или потенциальных работодателей) увидел код и сделал неверные выводы. Но сейчас решил: да пофиг, сделаю coming out. Программа-то полезная, и благодарных пользователей было много. Короче, это моя прога, и мне пофиг на качество кода, уже не стыдно.
Сейчас развивать её нет времени и желания (другие приоритеты), поэтому я перестал оплачивать домен. На Linux дистрибутивах сейчас есть Safe Eyes, и я рекомендую им пользоваться. Когда приходит время для перерыва, смотрите вдаль секунд на 20. И в долгосрочной перспективе это сильно поможет вам снизить нагрузку на зрение.
Чем из софтовых и физических решений для здоровья работников клавы и монитора вы пользуетесь?
Где-то году в 2011-м в новогодние каникулы я написал Windows программу, напоминающую делать перерывы, чтобы глаза отдыхали от дисплея. Мне самому такая была нужна, а существующие вариации мне не нравились. EyeLeo была небольшой бесплатной программой, но делающей важное дело, поэтому она быстро стала весьма популярной, и долгое время я получал небольшой доход с донатов (через Adsense и Patreon). Однако из-за очень низкого качества кода и общей игрушечности, я буквально скрывал принадлежность к EyeLeo. Мне не хотелось, чтобы кто-то из коллег (или потенциальных работодателей) увидел код и сделал неверные выводы. Но сейчас решил: да пофиг, сделаю coming out. Программа-то полезная, и благодарных пользователей было много. Короче, это моя прога, и мне пофиг на качество кода, уже не стыдно.
Сейчас развивать её нет времени и желания (другие приоритеты), поэтому я перестал оплачивать домен. На Linux дистрибутивах сейчас есть Safe Eyes, и я рекомендую им пользоваться. Когда приходит время для перерыва, смотрите вдаль секунд на 20. И в долгосрочной перспективе это сильно поможет вам снизить нагрузку на зрение.
Чем из софтовых и физических решений для здоровья работников клавы и монитора вы пользуетесь?
⚡️Видео When Nanoseconds Matter: Ultrafast Trading Systems
Довольно интересная лекция от David Gross из Optiver о том, какие фишки используются в проектировании комплексных торговых систем:
- как лучше представить L3 ордербук в памяти, и как искать в нем.
- немного о проектировании и коде SPMC bounded очереди в shared memory.
- идея spawn'ить perf прямо из своего процесса.
- немного о likely/unlikely/cold секциях в коде.
- упомнянул о том, какой выигрыш даёт kernel bypass при работе с сетью.
- использование clang xray для добавления профилирования в рантайме.
Довольно интересная лекция от David Gross из Optiver о том, какие фишки используются в проектировании комплексных торговых систем:
- как лучше представить L3 ордербук в памяти, и как искать в нем.
- немного о проектировании и коде SPMC bounded очереди в shared memory.
- идея spawn'ить perf прямо из своего процесса.
- немного о likely/unlikely/cold секциях в коде.
- упомнянул о том, какой выигрыш даёт kernel bypass при работе с сетью.
- использование clang xray для добавления профилирования в рантайме.
YouTube
When Nanoseconds Matter: Ultrafast Trading Systems in C++ - David Gross - CppCon 2024
https://cppcon.org
CppCon 2024 Early Access: https://cppcon.org/early-access
Access All 2024 Session Videos Ahead of Their Official Release To YouTube. At least 30 days exclusive access through the Early Access system. Videos will be released to the CppCon…
CppCon 2024 Early Access: https://cppcon.org/early-access
Access All 2024 Session Videos Ahead of Their Official Release To YouTube. At least 30 days exclusive access through the Early Access system. Videos will be released to the CppCon…
Месяц-два назад начал изучать новый язык, чего не делал уже несколько лет. Предыдущим новым языком был Golang аж в 2018-м, но он меня не вштырил, хотя были приятные моменты и откровения.
Что за язык то?
Вы угадаете его с 2х слов:
Подсказываю:
Правильно, этоРжавый .
Не буду ничего больше писать, а то получу сотни отписок от недовольных коллег по плюсам. Номне о н нравится .
Параллельно вникаю в Solana.
Что за язык то?
Вы угадаете его с 2х слов:
blazingly fast
.Подсказываю:
100% memory safe
.Правильно, это
Не буду ничего больше писать, а то получу сотни отписок от недовольных коллег по плюсам. Но
Параллельно вникаю в Solana.