-
Notifications
You must be signed in to change notification settings - Fork 17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
HF feeds and UI performance via throttling #192
Labels
data-layer
real-time and historical data processing and storage
perf
efficiency and latency optimization
(sub-)systems
general sw design and eng
testing
Comments
goodboy
added a commit
that referenced
this issue
Jun 15, 2021
Adding binance's "hft" ws feeds has resulted in a lot of context switching in our Qt charts, so much so it's chewin CPU and definitely worth it to throttle to the detected display rate as per discussion in issue #192. This is a first very very naive attempt at throttling L1 tick feeds on the `brokerd` end (producer side) using a constant and uniform delivery rate by way of a `trio` task + mem chan. The new func is `data._sampling.uniform_rate_send()`. Basically if a client request a feed and provides a throttle rate we just spawn a task and queue up ticks until approximately the next display rate's worth period of time has passed before forwarding. It's definitely nothing fancy but does provide fodder and a start point for an up and coming queueing eng to start digging into both #107 and #109 ;)
Merged
Another eventually relevant feature request is UDS support in |
goodboy
added a commit
that referenced
this issue
Sep 28, 2021
We are already packing framed ticks in extended lists from the `.data._sampling.uniform_rate_send()` task so the natural solution to avoid needless graphics cycles for HFT-ish feeds (like binance) is to unpack those frames and for most cases only update graphics with the "latest" data per loop iteration. Unpacking in this way also lessens nested-iterations per tick type. Btw, this also effectively solves all remaining issues of fast tick feeds over-triggering the graphics loop renders as long as the original quote stream is throttled appropriately, usually to the local display rate. Relates to #183, #192 Dirty deats: - drop all per-tick rate checks, they were always somewhat pointless when iterating a frame of ticks per render cycle XD. - unpack tick frame into ticks per frame type, and last of each type; the lasts are used to update each part of the UI/graphics by class. - only skip the label update if we can't retrieve the last from from a graphics source array; it seems `chart.update_curve_from_array()` already does a `len` check internally. - add some draft commented code for tick type classes and a possible wire framed tick data structure. - move `chart_maxmin()` range computer to module level, bind a chart to it with a `partial.` - only check rate limits in main quote loop thus reporting actual overages - add in commented logic for only updating the "last" cleared price from the most recent framed value if we want to eventually (right now seems like this is only relevant to ib and it's dark trades: `utrade`). - rename `_clear_throttle_rate` -> `_quote_throttle_rate`, drop `_book_throttle_rate`.
goodboy
added a commit
that referenced
this issue
Oct 28, 2021
We are already packing framed ticks in extended lists from the `.data._sampling.uniform_rate_send()` task so the natural solution to avoid needless graphics cycles for HFT-ish feeds (like binance) is to unpack those frames and for most cases only update graphics with the "latest" data per loop iteration. Unpacking in this way also lessens nested-iterations per tick type. Btw, this also effectively solves all remaining issues of fast tick feeds over-triggering the graphics loop renders as long as the original quote stream is throttled appropriately, usually to the local display rate. Relates to #183, #192 Dirty deats: - drop all per-tick rate checks, they were always somewhat pointless when iterating a frame of ticks per render cycle XD. - unpack tick frame into ticks per frame type, and last of each type; the lasts are used to update each part of the UI/graphics by class. - only skip the label update if we can't retrieve the last from from a graphics source array; it seems `chart.update_curve_from_array()` already does a `len` check internally. - add some draft commented code for tick type classes and a possible wire framed tick data structure. - move `chart_maxmin()` range computer to module level, bind a chart to it with a `partial.` - only check rate limits in main quote loop thus reporting actual overages - add in commented logic for only updating the "last" cleared price from the most recent framed value if we want to eventually (right now seems like this is only relevant to ib and it's dark trades: `utrade`). - rename `_clear_throttle_rate` -> `_quote_throttle_rate`, drop `_book_throttle_rate`.
goodboy
added a commit
that referenced
this issue
Oct 29, 2021
We are already packing framed ticks in extended lists from the `.data._sampling.uniform_rate_send()` task so the natural solution to avoid needless graphics cycles for HFT-ish feeds (like binance) is to unpack those frames and for most cases only update graphics with the "latest" data per loop iteration. Unpacking in this way also lessens nested-iterations per tick type. Btw, this also effectively solves all remaining issues of fast tick feeds over-triggering the graphics loop renders as long as the original quote stream is throttled appropriately, usually to the local display rate. Relates to #183, #192 Dirty deats: - drop all per-tick rate checks, they were always somewhat pointless when iterating a frame of ticks per render cycle XD. - unpack tick frame into ticks per frame type, and last of each type; the lasts are used to update each part of the UI/graphics by class. - only skip the label update if we can't retrieve the last from from a graphics source array; it seems `chart.update_curve_from_array()` already does a `len` check internally. - add some draft commented code for tick type classes and a possible wire framed tick data structure. - move `chart_maxmin()` range computer to module level, bind a chart to it with a `partial.` - only check rate limits in main quote loop thus reporting actual overages - add in commented logic for only updating the "last" cleared price from the most recent framed value if we want to eventually (right now seems like this is only relevant to ib and it's dark trades: `utrade`). - rename `_clear_throttle_rate` -> `_quote_throttle_rate`, drop `_book_throttle_rate`.
goodboy
added a commit
that referenced
this issue
Nov 2, 2021
We are already packing framed ticks in extended lists from the `.data._sampling.uniform_rate_send()` task so the natural solution to avoid needless graphics cycles for HFT-ish feeds (like binance) is to unpack those frames and for most cases only update graphics with the "latest" data per loop iteration. Unpacking in this way also lessens nested-iterations per tick type. Btw, this also effectively solves all remaining issues of fast tick feeds over-triggering the graphics loop renders as long as the original quote stream is throttled appropriately, usually to the local display rate. Relates to #183, #192 Dirty deats: - drop all per-tick rate checks, they were always somewhat pointless when iterating a frame of ticks per render cycle XD. - unpack tick frame into ticks per frame type, and last of each type; the lasts are used to update each part of the UI/graphics by class. - only skip the label update if we can't retrieve the last from from a graphics source array; it seems `chart.update_curve_from_array()` already does a `len` check internally. - add some draft commented code for tick type classes and a possible wire framed tick data structure. - move `chart_maxmin()` range computer to module level, bind a chart to it with a `partial.` - only check rate limits in main quote loop thus reporting actual overages - add in commented logic for only updating the "last" cleared price from the most recent framed value if we want to eventually (right now seems like this is only relevant to ib and it's dark trades: `utrade`). - rename `_clear_throttle_rate` -> `_quote_throttle_rate`, drop `_book_throttle_rate`.
goodboy
added a commit
that referenced
this issue
Nov 3, 2021
We are already packing framed ticks in extended lists from the `.data._sampling.uniform_rate_send()` task so the natural solution to avoid needless graphics cycles for HFT-ish feeds (like binance) is to unpack those frames and for most cases only update graphics with the "latest" data per loop iteration. Unpacking in this way also lessens nested-iterations per tick type. Btw, this also effectively solves all remaining issues of fast tick feeds over-triggering the graphics loop renders as long as the original quote stream is throttled appropriately, usually to the local display rate. Relates to #183, #192 Dirty deats: - drop all per-tick rate checks, they were always somewhat pointless when iterating a frame of ticks per render cycle XD. - unpack tick frame into ticks per frame type, and last of each type; the lasts are used to update each part of the UI/graphics by class. - only skip the label update if we can't retrieve the last from from a graphics source array; it seems `chart.update_curve_from_array()` already does a `len` check internally. - add some draft commented code for tick type classes and a possible wire framed tick data structure. - move `chart_maxmin()` range computer to module level, bind a chart to it with a `partial.` - only check rate limits in main quote loop thus reporting actual overages - add in commented logic for only updating the "last" cleared price from the most recent framed value if we want to eventually (right now seems like this is only relevant to ib and it's dark trades: `utrade`). - rename `_clear_throttle_rate` -> `_quote_throttle_rate`, drop `_book_throttle_rate`.
goodboy
added a commit
that referenced
this issue
Nov 3, 2021
We are already packing framed ticks in extended lists from the `.data._sampling.uniform_rate_send()` task so the natural solution to avoid needless graphics cycles for HFT-ish feeds (like binance) is to unpack those frames and for most cases only update graphics with the "latest" data per loop iteration. Unpacking in this way also lessens nested-iterations per tick type. Btw, this also effectively solves all remaining issues of fast tick feeds over-triggering the graphics loop renders as long as the original quote stream is throttled appropriately, usually to the local display rate. Relates to #183, #192 Dirty deats: - drop all per-tick rate checks, they were always somewhat pointless when iterating a frame of ticks per render cycle XD. - unpack tick frame into ticks per frame type, and last of each type; the lasts are used to update each part of the UI/graphics by class. - only skip the label update if we can't retrieve the last from from a graphics source array; it seems `chart.update_curve_from_array()` already does a `len` check internally. - add some draft commented code for tick type classes and a possible wire framed tick data structure. - move `chart_maxmin()` range computer to module level, bind a chart to it with a `partial.` - only check rate limits in main quote loop thus reporting actual overages - add in commented logic for only updating the "last" cleared price from the most recent framed value if we want to eventually (right now seems like this is only relevant to ib and it's dark trades: `utrade`). - rename `_clear_throttle_rate` -> `_quote_throttle_rate`, drop `_book_throttle_rate`.
goodboy
added a commit
that referenced
this issue
Nov 7, 2021
We are already packing framed ticks in extended lists from the `.data._sampling.uniform_rate_send()` task so the natural solution to avoid needless graphics cycles for HFT-ish feeds (like binance) is to unpack those frames and for most cases only update graphics with the "latest" data per loop iteration. Unpacking in this way also lessens nested-iterations per tick type. Btw, this also effectively solves all remaining issues of fast tick feeds over-triggering the graphics loop renders as long as the original quote stream is throttled appropriately, usually to the local display rate. Relates to #183, #192 Dirty deats: - drop all per-tick rate checks, they were always somewhat pointless when iterating a frame of ticks per render cycle XD. - unpack tick frame into ticks per frame type, and last of each type; the lasts are used to update each part of the UI/graphics by class. - only skip the label update if we can't retrieve the last from from a graphics source array; it seems `chart.update_curve_from_array()` already does a `len` check internally. - add some draft commented code for tick type classes and a possible wire framed tick data structure. - move `chart_maxmin()` range computer to module level, bind a chart to it with a `partial.` - only check rate limits in main quote loop thus reporting actual overages - add in commented logic for only updating the "last" cleared price from the most recent framed value if we want to eventually (right now seems like this is only relevant to ib and it's dark trades: `utrade`). - rename `_clear_throttle_rate` -> `_quote_throttle_rate`, drop `_book_throttle_rate`.
goodboy
added a commit
that referenced
this issue
Dec 7, 2021
We are already packing framed ticks in extended lists from the `.data._sampling.uniform_rate_send()` task so the natural solution to avoid needless graphics cycles for HFT-ish feeds (like binance) is to unpack those frames and for most cases only update graphics with the "latest" data per loop iteration. Unpacking in this way also lessens nested-iterations per tick type. Btw, this also effectively solves all remaining issues of fast tick feeds over-triggering the graphics loop renders as long as the original quote stream is throttled appropriately, usually to the local display rate. Relates to #183, #192 Dirty deats: - drop all per-tick rate checks, they were always somewhat pointless when iterating a frame of ticks per render cycle XD. - unpack tick frame into ticks per frame type, and last of each type; the lasts are used to update each part of the UI/graphics by class. - only skip the label update if we can't retrieve the last from from a graphics source array; it seems `chart.update_curve_from_array()` already does a `len` check internally. - add some draft commented code for tick type classes and a possible wire framed tick data structure. - move `chart_maxmin()` range computer to module level, bind a chart to it with a `partial.` - only check rate limits in main quote loop thus reporting actual overages - add in commented logic for only updating the "last" cleared price from the most recent framed value if we want to eventually (right now seems like this is only relevant to ib and it's dark trades: `utrade`). - rename `_clear_throttle_rate` -> `_quote_throttle_rate`, drop `_book_throttle_rate`.
goodboy
added a commit
that referenced
this issue
Dec 9, 2021
We are already packing framed ticks in extended lists from the `.data._sampling.uniform_rate_send()` task so the natural solution to avoid needless graphics cycles for HFT-ish feeds (like binance) is to unpack those frames and for most cases only update graphics with the "latest" data per loop iteration. Unpacking in this way also lessens nested-iterations per tick type. Btw, this also effectively solves all remaining issues of fast tick feeds over-triggering the graphics loop renders as long as the original quote stream is throttled appropriately, usually to the local display rate. Relates to #183, #192 Dirty deats: - drop all per-tick rate checks, they were always somewhat pointless when iterating a frame of ticks per render cycle XD. - unpack tick frame into ticks per frame type, and last of each type; the lasts are used to update each part of the UI/graphics by class. - only skip the label update if we can't retrieve the last from from a graphics source array; it seems `chart.update_curve_from_array()` already does a `len` check internally. - add some draft commented code for tick type classes and a possible wire framed tick data structure. - move `chart_maxmin()` range computer to module level, bind a chart to it with a `partial.` - only check rate limits in main quote loop thus reporting actual overages - add in commented logic for only updating the "last" cleared price from the most recent framed value if we want to eventually (right now seems like this is only relevant to ib and it's dark trades: `utrade`). - rename `_clear_throttle_rate` -> `_quote_throttle_rate`, drop `_book_throttle_rate`.
goodboy
added a commit
that referenced
this issue
Jan 14, 2022
We are already packing framed ticks in extended lists from the `.data._sampling.uniform_rate_send()` task so the natural solution to avoid needless graphics cycles for HFT-ish feeds (like binance) is to unpack those frames and for most cases only update graphics with the "latest" data per loop iteration. Unpacking in this way also lessens nested-iterations per tick type. Btw, this also effectively solves all remaining issues of fast tick feeds over-triggering the graphics loop renders as long as the original quote stream is throttled appropriately, usually to the local display rate. Relates to #183, #192 Dirty deats: - drop all per-tick rate checks, they were always somewhat pointless when iterating a frame of ticks per render cycle XD. - unpack tick frame into ticks per frame type, and last of each type; the lasts are used to update each part of the UI/graphics by class. - only skip the label update if we can't retrieve the last from from a graphics source array; it seems `chart.update_curve_from_array()` already does a `len` check internally. - add some draft commented code for tick type classes and a possible wire framed tick data structure. - move `chart_maxmin()` range computer to module level, bind a chart to it with a `partial.` - only check rate limits in main quote loop thus reporting actual overages - add in commented logic for only updating the "last" cleared price from the most recent framed value if we want to eventually (right now seems like this is only relevant to ib and it's dark trades: `utrade`). - rename `_clear_throttle_rate` -> `_quote_throttle_rate`, drop `_book_throttle_rate`.
goodboy
added a commit
that referenced
this issue
Jan 21, 2022
We are already packing framed ticks in extended lists from the `.data._sampling.uniform_rate_send()` task so the natural solution to avoid needless graphics cycles for HFT-ish feeds (like binance) is to unpack those frames and for most cases only update graphics with the "latest" data per loop iteration. Unpacking in this way also lessens nested-iterations per tick type. Btw, this also effectively solves all remaining issues of fast tick feeds over-triggering the graphics loop renders as long as the original quote stream is throttled appropriately, usually to the local display rate. Relates to #183, #192 Dirty deats: - drop all per-tick rate checks, they were always somewhat pointless when iterating a frame of ticks per render cycle XD. - unpack tick frame into ticks per frame type, and last of each type; the lasts are used to update each part of the UI/graphics by class. - only skip the label update if we can't retrieve the last from from a graphics source array; it seems `chart.update_curve_from_array()` already does a `len` check internally. - add some draft commented code for tick type classes and a possible wire framed tick data structure. - move `chart_maxmin()` range computer to module level, bind a chart to it with a `partial.` - only check rate limits in main quote loop thus reporting actual overages - add in commented logic for only updating the "last" cleared price from the most recent framed value if we want to eventually (right now seems like this is only relevant to ib and it's dark trades: `utrade`). - rename `_clear_throttle_rate` -> `_quote_throttle_rate`, drop `_book_throttle_rate`.
goodboy
added a commit
that referenced
this issue
Jan 23, 2022
We are already packing framed ticks in extended lists from the `.data._sampling.uniform_rate_send()` task so the natural solution to avoid needless graphics cycles for HFT-ish feeds (like binance) is to unpack those frames and for most cases only update graphics with the "latest" data per loop iteration. Unpacking in this way also lessens nested-iterations per tick type. Btw, this also effectively solves all remaining issues of fast tick feeds over-triggering the graphics loop renders as long as the original quote stream is throttled appropriately, usually to the local display rate. Relates to #183, #192 Dirty deats: - drop all per-tick rate checks, they were always somewhat pointless when iterating a frame of ticks per render cycle XD. - unpack tick frame into ticks per frame type, and last of each type; the lasts are used to update each part of the UI/graphics by class. - only skip the label update if we can't retrieve the last from from a graphics source array; it seems `chart.update_curve_from_array()` already does a `len` check internally. - add some draft commented code for tick type classes and a possible wire framed tick data structure. - move `chart_maxmin()` range computer to module level, bind a chart to it with a `partial.` - only check rate limits in main quote loop thus reporting actual overages - add in commented logic for only updating the "last" cleared price from the most recent framed value if we want to eventually (right now seems like this is only relevant to ib and it's dark trades: `utrade`). - rename `_clear_throttle_rate` -> `_quote_throttle_rate`, drop `_book_throttle_rate`.
3 tasks
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Labels
data-layer
real-time and historical data processing and storage
perf
efficiency and latency optimization
(sub-)systems
general sw design and eng
testing
Since the addition of
binance
provider support in #170 i've noticed some serious cpu usage on weaker hw due the high data rates received on the binance websocket pipes. The L1 quote rates in particular can be instantaneous rates 500-1kHz which far and above now only most 60FPS display rates but even higher end stuff.This issue can be considered a partial followup subtask for #180.
Toolz
perf-timer
's async support to figure out exactly which tasks are causing the most cpu gobblePremises
Qt
UIs we shouldn't need to update graphics more then 60 FPS from a data feed, any more then this is just wasted cyclesQt
task switches at greater then refresh rates which, for data viz purposes, is likely pointless.> 5
symbols loaded in the local chart cache; you'll start to notice the usage in a sys monitor as well as light latency when scrolling/panning in the view box with the mouse.trio
, though it seems this would be doubting the OS's IO latency?Solution ideas to try
tractor
?msgspec
in Try msgspec goodboy/tractor#212 but the improvement is negligible (as would be expected for encode only atm)data.feed
layer?open_feed()
that could then be used to limit the publisher-bus side send loop; it would in theory save bandwidth and would beN
less loops cycling, where there areN
UIs in need of such a rate limit (i.e. throttle at the fan-out source).open_feed()
stream to be a newtractor
2-way stream and allow sending dynamicoff
/on
messages to pause / resume the stream? I can't see this being latent and should be relatively simple to implement.pikerd
tree potentially anyway to support long running fsp triggered alerts / stratsbrokerd
actors, so this likely has little effect at small scale.tractor
bidir apis into each provider'sstream_quotes()
routine and launching another task to handle inbound subscription change messages such as in the newtractor
dynamic pub-sub examplesThe text was updated successfully, but these errors were encountered: