Open niclar opened 1 year ago
@niclar I do not completely understand your question.
What kind of problem are you trying to solve?
Yes exposing the listener working thread , the std::thread
or std::thread::native_handle
would facilitate modifying the thread directly. In my case multiple listeners was allocated to the same core but I wanted explicit allocation / pinning for lower contention / latency & I can also name the work threads via the underlying thread / thread handle for faster debugging.
@niclar
Yes exposing the listener working thread , the std::thread or std::thread::native_handle would facilitate modifying the thread directly.
We have already written a posix::Thread wrapper which will be used there as an underlying thread type.
I can also name the work threads via the underlying thread / thread handle for faster debugging.
With this change you wouldn't be able to acquire the native_handle but you could still set a name for the thread.
In my case multiple listeners was allocated to the same core but I wanted explicit allocation / pinning for lower contention / latency
Getting access to the thread wouldn't achieve your goal. In the end the thread in the listener just iterates over an array of events and calls the callbacks. If you would like to add more jobs to the thread you would require some active object pattern and add multiple listeners to the same object. Something which not yet have designed and it would take a while to rewrite our architecture.
The idea of the listener was to have exactly one per core. Why do you use multiple listeners per core?
"If you would like to add more jobs to the thread" -we're fine with dedicating a worker thread per listener.
-On a somewhat related note, we're hitting the maximum number of condition variables per listener limit (256), what would be recommended maximum on x64 linux (not to decrease performance, any obvious downsides to setting it to e.g 2048? ) ?
"Why do you use multiple listeners per core" -it's unintended. The linux scheduler does that when running under core isolation and tasksets for some reason.
-As for the native thread handle. If we can get hold of it using the public interface it would be of great convenience.
@niclar
On a somewhat related note, we're hitting the maximum number of condition variables per listener limit (256), what would be recommended maximum on x64 linux (not to decrease performance, any obvious downsides to setting it to e.g 2048? ) ?
There is no real recommendation. But you have to be aware that the higher the number is the slower the waitset is. Here I would recommend to write a little benchmark with your most common use case and optimize it so that it meets your target requirements. I think also that the performance decrease comes in steps. For instance that it decrease every additional 1024 entries and stays the same in the range from 1024 - 2047.
As for the native thread handle. If we can get hold of it using the public interface it would be of great convenience.
I would here recommend that we adjust the listener API so that we provide a builder for the listener where also settings of the underlying thread can be configured. Stuff like: cpu affinity, priority, name. @niclar would this fit your use case?
@elBoberido what do you think about a listener builder?
@elfenpiff a listener builder would be great
@elfenpiff -Yeah, for sure, sounds like real luxury :)
@niclar At the moment we are in the middle of making iceoryx ready to be used in a safety critical context. The features you request:
Listener
with a builderSubscriber
with some additional infos about the current buffer capacity/sizewould be awesome to have for the open source community version but I think we will not have the capacity soon to realize them. So we have three options:
Using the listener construct, it would be nice to get hold of the worker thread and pin it on startup (etc) without resorting to reinterpret_cast hacks.
-Or is it that outside the intended use case for listener maybe ?
Best,