20#include "fastmm/core/config_macros.hpp"
21#include "fastmm/core/latency.hpp"
23#include "fastmm/core/msg_ring.hpp"
34struct WireLatencyStats {
35 std::uint64_t
count = 0;
56 Cycles after_send)
noexcept {
57 if (batching_ && batch_len_ <
kMaxBatch) {
58 batch_[batch_len_++] = Staged{t0, before_encode, after_encode};
61 record_now(t0, before_encode, after_encode, after_send);
73 for (std::size_t i = 0; i < batch_len_; ++i) {
74 const Staged& s = batch_[i];
75 record_now(s.t0, s.before_encode, s.after_encode, after_send);
82 [[nodiscard]] LogLinearHistogram
encode() const noexcept {
return encode_.total(); }
83 [[nodiscard]] LogLinearHistogram
send() const noexcept {
return send_.total(); }
84 [[nodiscard]] LogLinearHistogram
tick_to_trade() const noexcept {
return tick_to_trade_.total(); }
93 fill(encode_.total(), c,
encode);
94 fill(send_.total(), c,
send);
105 tick_to_trade_.roll(now_ns);
106 encode_.roll(now_ns);
109 fill(tick_to_trade_.last_minute(), c, last_minute.tick_to_trade);
110 fill(encode_.last_minute(), c, last_minute.encode);
111 fill(send_.last_minute(), c, last_minute.send);
112 fill(tick_to_trade_.last_hour(), c, last_hour.tick_to_trade);
113 fill(encode_.last_hour(), c, last_hour.encode);
114 fill(send_.last_hour(), c, last_hour.send);
117 void reset() noexcept {
120 tick_to_trade_.reset();
130 FASTMM_FORCE_INLINE
void record_now(
Cycles t0,
133 Cycles after_send)
noexcept {
134 encode_.record(delta(after_encode, before_encode));
135 send_.record(delta(after_send, after_encode));
136 if (t0.v != 0) tick_to_trade_.record(delta(after_send, t0));
138 [[nodiscard]]
static std::uint64_t delta(Cycles later, Cycles earlier)
noexcept {
139 return later.v > earlier.v ? later.v - earlier.v : 0;
141 [[nodiscard]]
static std::uint64_t to_ns(std::uint64_t cycles,
const TscCalibration& c)
noexcept {
144 static void fill(
const LogLinearHistogram& h,
145 const TscCalibration& c,
146 WireLatencyStats& out)
noexcept {
147 out.count = h.count();
148 out.p50_ns = to_ns(h.percentile(0.50), c);
149 out.p99_ns = to_ns(h.percentile(0.99), c);
150 out.p999_ns = to_ns(h.percentile(0.999), c);
151 out.max_ns = to_ns(h.max(), c);
154 RecentHistogram encode_;
155 RecentHistogram send_;
156 RecentHistogram tick_to_trade_;
158 std::size_t batch_len_ = 0;
159 bool batching_ =
false;
179 void clear() noexcept { len_ = 0; }
181 if (len_ < entries_.size())
182 entries_[len_++] =
Entry{c.
kind, c.instrument, c.cl_ord_id, c.orig_cl_ord_id};
184 [[nodiscard]] std::span<const Entry>
entries() const noexcept {
return {entries_.data(), len_}; }
187 std::array<Entry, WireLatencyRecorder::kMaxBatch> entries_{};
188 std::size_t len_ = 0;
195 explicit OutboundBatch(std::span<const EventHeader* const> batch) noexcept : batch_(batch) {}
196 [[nodiscard]]
const std::byte*
try_peek() const noexcept {
197 return next_ < batch_.size() ?
reinterpret_cast<const std::byte*
>(batch_[next_]) : nullptr;
199 void release() noexcept { ++next_; }
202 std::span<const EventHeader* const> batch_;
203 std::size_t next_ = 0;
211template <
class Ring,
class Cork,
class OnMessage,
class Uncork>
213 Ring& ring,
WireLatencyRecorder& wire, Cork&& cork, OnMessage&& on_message, Uncork&& uncork) {
214 while (ring.try_peek() !=
nullptr) {
218 const std::byte* p = ring.try_peek();
219 if (p ==
nullptr)
break;
220 on_message(*
reinterpret_cast<const EventHeader*
>(p));
223 const bool sent = uncork();
void note(const OrderCommand &c) noexcept
Definition wire_latency.hpp:182
std::span< const Entry > entries() const noexcept
Definition wire_latency.hpp:186
void clear() noexcept
Definition wire_latency.hpp:181
The engine's batch handed over directly (run-to-completion, Venue::send_now) behind the consumer side...
Definition wire_latency.hpp:195
const std::byte * try_peek() const noexcept
Definition wire_latency.hpp:198
void release() noexcept
Definition wire_latency.hpp:201
Definition wire_latency.hpp:51
void reset() noexcept
Definition wire_latency.hpp:119
void begin_batch() noexcept
Definition wire_latency.hpp:66
static constexpr std::size_t kMaxBatch
Definition wire_latency.hpp:53
LogLinearHistogram send() const noexcept
Definition wire_latency.hpp:85
LogLinearHistogram encode() const noexcept
The session's samples.
Definition wire_latency.hpp:84
void summarize(const TscCalibration &c, WireLatencyStats &tick_to_trade, WireLatencyStats &encode, WireLatencyStats &send) const noexcept
Percentiles in ns under c's TSC rate (also set when only constant_tsc is present); without a rate onl...
Definition wire_latency.hpp:90
FASTMM_FORCE_INLINE void record(Cycles t0, Cycles before_encode, Cycles after_encode, Cycles after_send) noexcept
Definition wire_latency.hpp:55
void end_batch(Cycles after_send, bool sent) noexcept
sent: the batch's write succeeded (or was queued); false drops the kept stamps.
Definition wire_latency.hpp:72
LogLinearHistogram tick_to_trade() const noexcept
Definition wire_latency.hpp:86
bool batch_full() const noexcept
Definition wire_latency.hpp:70
Event bus message structs (5.5).
void drain_outbound_coalesced(Ring &ring, WireLatencyRecorder &wire, Cork &&cork, OnMessage &&on_message, Uncork &&uncork)
Drains the engine's outbound ring (or an OutboundBatch) in batches of at most kMaxBatch messages: cor...
Definition wire_latency.hpp:214
OrderCommandKind
Definition order_commands.hpp:15
FASTMM_FORCE_INLINE std::uint64_t tsc_interval_ns(const TscCalibration &c, std::uint64_t cycles) noexcept
A TSC cycle interval in ns; 0 without a rate.
Definition time.hpp:101
FASTMM_FORCE_INLINE Cycles rdtscp() noexcept
Serialising read (rdtscp) is what latency hops want: it waits for prior loads to retire.
Definition time.hpp:66
OrderCommand: a uniform, non-owning view over the three outbound engine messages (OutNewOrderMsg / Ou...
Definition wire_latency.hpp:174
InstrumentId instrument
Definition wire_latency.hpp:176
OrderCommandKind kind
Definition wire_latency.hpp:175
ClientOrderId cl_ord_id
Definition wire_latency.hpp:177
ClientOrderId orig_cl_ord_id
Replace only.
Definition wire_latency.hpp:178
Definition order_commands.hpp:28
Definition wire_latency.hpp:36
std::uint64_t p99_ns
Definition wire_latency.hpp:39
std::uint64_t max_ns
Definition wire_latency.hpp:41
std::uint64_t p50_ns
Definition wire_latency.hpp:38
std::uint64_t count
Definition wire_latency.hpp:37
std::uint64_t p999_ns
Definition wire_latency.hpp:40
The three over one window (WireLatencyRecorder::summarize).
Definition wire_latency.hpp:45
WireLatencyStats tick_to_trade
Definition wire_latency.hpp:46
WireLatencyStats send
Definition wire_latency.hpp:48
WireLatencyStats encode
Definition wire_latency.hpp:47