-
Notifications
You must be signed in to change notification settings - Fork 865
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
Improving CUnitQueue performance and data race tolerance #2395
Improving CUnitQueue performance and data race tolerance #2395
Conversation
32 * 1500B = 48000B = 48KB? |
|
If there is only one socket bound to the receiving queue, there should be no fragmentation, and |
In earlier days I was researching the possibility of reception from multiple sockets. There are two methods how you could do it:
|
8bd763a
to
026b5b3
Compare
026b5b3
to
eb700a6
Compare
using an atomic. Refactored common allocation code CUnitQueue::allocateEntry(..).
Allocates 128 additional units at the start and every time 90% of units are taken. Previously was allocating only 32 units.
eb700a6
to
7c81569
Compare
|
||
CUnit* m_pAvailUnit; // recent available unit | ||
/// Increase the unit queue size (by @a m_iBlockSize units). | ||
/// Uses m_mtx to protect access and changes of the queue state. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
m_mtx
was deleted?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. There is no sense in it with the atomic m_iFlag
. But I forgot to update the comment :)
Thanks for noticing!
You do not specify a memory order when storing or reading from |
@wednesdayfrogcoder |
Protect CUnitQueue from data race
Protect CUnitQueue from data race with a dedicated mutex and atomics.
Previously only
CUnitQueue::m_iCount
was protected being of an atomic type.However, a simultaneous access to
CUnit::m_iFlag
was possible fromCUnitQueue::getNextAvailUnit()
(RcvQ thread) andCUnitQueue::makeUnitFree()
(RCV reading thread), see sanitizer warning below.There is also no protection from simultaneous calls to
CUnitQueue::getNextAvailUnit()
from different threads. However, currently, it is not done. Just added a comment for future consideration if this changes.As we don't want to block 'makeUnitFree()
and
makeUnitGood()on a mutex while new units are being allocated or a free one is being searched,
CUnit::m_iFlagand
CUnitQueue::m_iNumTaken` are marked atomic and don't have to be protected by a mutex. The rest variables are left unprotected as supposed to be accessed from the same thread (RcvQ thread).Marking each
CUnit::m_iFlag
atomic might have a memory overhead and some performance burden accessing it from the receiver buffer, etc. However, Comparing atomic, mutex, rwlocks/ states atomics are still better in terms of performance.Increased CUnitQueue block size
CUnitQueue
allocates 32 additional units at the start and every time 90% of units are taken.32 units of 1500 bytes equal to ~384 kbits. For example SRT buffering latency of 100ms it covers 3 Mbps stream.
For example, SRT buffering latency of 1 second covers 384 kbps stream.
Raising the size of the block to 128 units or 1.5 Mbits is at least closer to some real bitrates of a live video stream. Also
CUnitQueue::increase()
would be called less frequently, as each increase now allocated 1.5 Mbits instead of 384 kbits.Likely resolves #2346 together with #2405.
RAII for
CUnitQueue
Previously
CUnitQueue()
construction andCUnitQueue::init()
were different functions. Now constructor allocates all necessary resources. It also allows making theCUnitQueue::m_iMSS
constant, as all units are expected to be of the same size.