Skip to content
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 sending queue sleepto() accuracy #678

Merged
merged 1 commit into from
Aug 19, 2019

Conversation

maxsharabayko
Copy link
Collaborator

@maxsharabayko maxsharabayko commented May 8, 2019

The sleeping time for the SRT sending queue is 10 ms, and it is discrete.
That means, if a thread wants to sleep for 5 ms, it will sleep for 10 ms.
If a thread wants to sleep for 15 ms, it will sleep for 10 ms, and then again for another 10 ms, that will make a total sleep time of 20 ms.
This behavior is incorrect and unnecessary.

Fixes #673.

TODO

Accuracy of the new sleepto()

  • Windows 10 test sleepto function accuracy
  • Linux test sleepto function accuracy
  • MacOS test sleepto function accuracy
  • Other platforms (iOS, Android, etc.)

Accuracy on Windows

  • Check accuracy of CreateWaitableTimer
  • Check whether increasing thread/process priority increasing the timing accuracy.

Live mode sending accuracy

  • Windows 10 sender accuracy measurements (based on pcapng)
  • Linux sender accuracy measurements (based on pcapng)
  • MacOS sender accuracy measurements (based on pcapng)

File mode sending accuracy

  • Sending

Do we need a maximum sleeping time of 10 ms?

In pseudocode, the sleepto function works like this:

CTimer::sleepto(nexttime) {
    m_ullSchedTime = nexttime;
    rdtsc(now);
    while (now < m_ullSchedTime) {
        condTimedWaitUS(&m_TickCond, &m_TickLock, (m_ullSchedTime- now));
        rdtsc(now);
    }
}

CTimer::sleepto(nexttime) waits on a CV m_TickCond.

CTimer::tick() function

The function CTimer::tick() signals this CV, and it will break the wait to force time checking. The tick() function is called from the receiving thread in CRcvQueue::worker_RetrieveUnit() before every operation of reading data from the socket. This is probably wrong, but requires further review.

CTimer::interrupt() function

In case the thread has to be forced break, there is another function CTimer::interrupt(), that changes the m_ullSchedTime to he current time and calls tick() to break any waits.

Conclusion

This means that maximum waiting time of 10 ms is not necessary.

Do we need a minimum allowed sleeping time?

As shown in #637, the sleepto() function has certain inaccuracy.

A final matrix to be placed here.

CTimer::sleepto() accuracy (proposed implementation) in CV-based waiting mode. Each column shows the actual sleeping time in microseconds for each platform. Measured using unit test CTimer.SleeptoAccuracy.

Time, μs Win 10 CentOS 7 MacBook Pro iOS Android
1 64 49 1
5 209 58 10
10 354 62 17
50 1181 99 68
100 1536 150 140
250 1559 315 389
500 1469 582 738
1000 1593 1080 1346
5000 5506 5110 6118
10000 10717 10112 11963

@maxsharabayko maxsharabayko added the [core] Area: Changes in SRT library core label May 8, 2019
@maxsharabayko maxsharabayko added this to the v.1.3.3 milestone May 8, 2019
@maxsharabayko maxsharabayko force-pushed the develop/busy_waiting branch 2 times, most recently from a494ce6 to 7d049ca Compare May 9, 2019 12:40
@maxsharabayko maxsharabayko force-pushed the develop/busy_waiting branch 2 times, most recently from b3aa812 to d6e3f8b Compare May 28, 2019 14:07
@maxsharabayko
Copy link
Collaborator Author

maxsharabayko commented May 28, 2019

Wireshark captures were recorded during sending sessions. Based on the capture files, the time intervals between packets can be calculated. Based on the inter-packet times measurements, mean (average) sending rate, standard deviation and oscilation measurements are calculated on three intervals: 1 sec, 100 ms and 10 ms.
The following results show improvements in sending accuracy on Linux, mostly at high bitrates (above 100 Mbps).

Sender: CentOS 7

500 Mbps

Approximate target inter packet time 24 μs.

Alg 1 sec 100 ms 10 ms
mean std S mean std S mean std S
default 518 40,9
0.000789 517 25,9 0.050163 517 35,6 0.068952
PR 518 31,4 0.000605 517 28,2 0.054498 517 28,8 0.055761
Default sleepto() at 100 ms resolution

centos-istd0-sleepto0-blt-500Mbps-100ms

PR sleepto() at 100 ms resolution

centos-istd0-sleepto3-blt-500Mbps-100ms

Default sleepto() at 10 ms resolution

centos-istd0-sleepto0-blt-500Mbps-10ms

PR sleepto() at 10 ms resolution

centos-istd0-sleepto3-blt-500Mbps-10ms

100 Mbps

Approximate target inter packet time 120 μs.

Alg 1 sec 100 ms 10 ms
mean std S mean std S mean std S
default 103 1,59 0,015416 103 5,04 0,048903 103 6,28 0,060979
PR 103 1,61 0,015611 103 5,10 0,049462 103 5,79 0,056257

1 Mbps

Approximate target inter packet time 12 ms.

Alg 1 sec 100 ms 10 ms
mean std S mean std S mean std S
default 1,02 0,002 0,00215 1,02 0,006 0,05894 1,02 0,004 0,42051
PR 1,02 0,002 0,00215 1,02 0,006 0,05894 1,02 0,004 0,42051

@maxsharabayko maxsharabayko modified the milestones: v.1.3.3, v.1.3.4 May 29, 2019
@maxsharabayko maxsharabayko force-pushed the develop/busy_waiting branch 2 times, most recently from 04d71bf to 05951b1 Compare August 2, 2019 09:33
@maxsharabayko maxsharabayko marked this pull request as ready for review August 2, 2019 09:47
@rndi rndi self-requested a review August 17, 2019 01:45
Default sleep of 10 ms replaced with actual desired sleeping time.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[core] Area: Changes in SRT library core
Projects
None yet
Development

Successfully merging this pull request may close these issues.

gstreamer - high IAT(Inter Arrival Time) around ~10ms observed between UDP datagrams of SRT client output
2 participants