-
Notifications
You must be signed in to change notification settings - Fork 12
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
Design Change of Tag
#391
Comments
After a design iteration with @ivan-cukic, we have settled on the following revised struct alignas(std::hardware_constructive_interference_size) Tag {
// size: 192 bytes (N.B. cache-aligned)
using index_type = std::size_t;
using property_map = std::map<std::string, pmt::pmtv>; // 48 bytes
index_type _index{0}; // 4 or 8 bytes
bool isEndOfStream : 1 = false;
bool isTrigger : 1 = false;
bool hasContextDefined : 1 = false;
std::size_t _unused : (sizeof(std::size_t) * 8) - 3 = 0; // 4 or 8 bytes with the above
// add more bitfields as needed
std::uint64_t trigger_time{0UZ}; // 8 bytes
float trigger_offset{.0f}; // 4 bytes
pmt::pmtv trigger_name;
pmt::pmtv ctx;
property_map map{};
constexpr void clearFlags() noexcept {
isEndOfStream = false;
isTrigger = false;
hasContextDefined = false;
_unused = 0;
}
constexpr void clear() noexcept {
clearFlags();
map.clear();
trigger_time = 0UZ;
trigger_offset = .0f;
trigger_name = std::monostate{};
ctx = std::monostate{};
}
}; This |
There is a test-branch implementing this feature. Will leave this open for some time for others to give it a try/diagnose the real bottlenecks and then close it otherwise. |
I will close this as it is idle and unlikely to be followed up (the corresponding branch is lagging too much behind). |
Add frequently used
Tag
Infos as strongly-typed fields or as part of a bit-field maskIn GR4 we use
Tag
as a standardised form to annotate streams, indicate trigger, context changes, or settings changes that should be downstream propagated within a graph. The initial design assumption was thatTag
s are rare compared to the payload stream frequency they are attached to (e.g. one tag every ~1024 samples or more). Pushing the envelope a bit further and publishing, for example (worst case), a tag on every float sample, we noticed that the event handling rate goes down to ~300 kMsgs/s. Semën Lebedev wrote a new performance monitor block that can be inserted anywhere in the graph and track the throughput performance and memory consumption: #358For the typical use case, the given Tag[Source, Monitor, Sink] graph topology (blocks are non-trivial) can be run up to about 500 MS/s (and Tags roughly every 1k samples) but drops down to about 30 kMsg/s when there is a tag attached to every sample. This is probably acceptable for most real-world use cases. Still, we felt that this could be further improved as the main bottleneck turned out to be the access of Tag meta information in the
property_map
(which internally is astd::map<std::string, pmt::pmtv>
) and often just to check if there is an end-of-stream (EoS) tag in the stream. The frequent map accesses make the processing slow.Thus, we tinkered and played with the idea of modifying the existing
Tag
definition from:to a slightly larger structure where certain common fields and key-value pairs are hard-coded, namely:
The rationale behind the proposed changes is to minimise the access times to the
using property_map = std::map<std::string, pmt::pmtv>;
that are non-negligible in case there is a tag, for example, on every sample. See for instance, https://quick-bench.com/q/P7GaIXJLAJfnhCUT_29J6J7S-LYThe other update is how to generalise the tag forwarding using meta-programming. We can provide default implementations for the first ones:
But we hit too many corner cases for the last one. Meta-programming read: C++ only, and/or it would be hard to wrap/write reasonably performing Python wrappers for it. We can post the exact signature later, but in a nutshell, it's similar to the for-each-port method, but it provides both input and output streaming ports.
I hope the design above is reasonable. There are the following main items to be discussed:
trigger_name
is presently astd::string
but we thought of also allowing apmt::pmtv
type for a more economic, for example, int-based comparisons.ctx
as key, as this drives a lot of the multiplexing and settings updates. Similar open question to the trigger:std::string
and/orpmt::pmtv
.The text was updated successfully, but these errors were encountered: