Ответ
Один из самых интересных проектов — это разработка высокопроизводительного трейдингового движка (market data processor) на C++ для фондовой биржи. Задача заключалась в обработке потоков рыночных данных (order book updates) с латентностью менее 100 микросекунд.
Мой вклад и решенные технические задачи:
-
Оптимизация обработки сообщений: Мы отказались от динамических аллокаций в «горячем» пути. Использовали кольцевые буферы (ring buffers) на основе предварительно выделенных массивов и атомарных операций для обмена данными между потоками (producer-consumer pattern).
template<typename T, size_t Size> class SPSCRingBuffer { std::array<T, Size> buffer_{}; std::atomic<size_t> head_{0}, tail_{0}; public: bool try_push(T&& item) noexcept { /* ... lock-free enqueue */ } bool try_pop(T& item) noexcept { /* ... lock-free dequeue */ } }; -
Снижение латентности сети: Для приема UDP-мультикаст-потоков использовали
boost::asioв режиме низкой латентности, настройку сокетов (SO_RCVBUF) и привязку потоков к конкретным CPU-ядрам (pthread_setaffinity_np) для минимизации переключений контекста и кэш-промахов. -
Профилирование и оптимизация: Активно использовали
perf,Intel VTuneиValgrind/Callgrindдля поиска узких мест. Одной из ключевых оптимизаций была замена полиморфных вызовов виртуальных функций на шаблонный CRTP (Curiously Recurring Template Pattern) для статического полиморфизма, что устранило затраты на косвенные вызовы и улучшило предсказание ветвлений.
Результат: Нам удалось достичь стабильной латентности обработки в ~85 микросекунд на 99-м перцентиле, что соответствовало жестким требованиям заказчика. Проект был сложным, но дал бесценный опыт в low-level оптимизациях, многопоточности и работе с реальным hardware.