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

m_iRTT and m_iRTTVar double EWMA #782

Closed
smsajjadi opened this issue Aug 1, 2019 · 9 comments · Fixed by #1957
Closed

m_iRTT and m_iRTTVar double EWMA #782

smsajjadi opened this issue Aug 1, 2019 · 9 comments · Fixed by #1957
Assignees
Labels
[core] Area: Changes in SRT library core Type: Maintenance Work required to maintain or clean up the code
Milestone

Comments

@smsajjadi
Copy link

smsajjadi commented Aug 1, 2019

Calculation of m_iRTT/m_iRTTVar values from ACKACK trip times already has a moving average (line 6964 of core.cpp) :

  m_iRTTVar = avg_iir<4>(m_iRTTVar, abs(rtt - m_iRTT));
  m_iRTT = avg_iir<8>(m_iRTT, rtt);

Then they are sent back through the ACK packets, and then the sender side performs another EWMA on them (line 7023 of core.cpp):

  // RTT EWMA
  m_iRTTVar = (m_iRTTVar * 3 + abs(rtt - m_iRTT)) >> 2;
  m_iRTT = (m_iRTT * 7 + rtt) >> 3;

Was it really intended? If yes, for what sake?

@jeandube
Copy link
Collaborator

jeandube commented Aug 1, 2019

I checked in the original UDT4 code and this is effectively an addition for which I have no explanation. The ''avg_iir'' was not in UDT4, so this is an addition from a C++ programmer, which I am not :-)

@maxsharabayko
Copy link
Collaborator

maxsharabayko commented Aug 1, 2019

I would say the IIR filtering is performed for the second time on the sender's side, because of the generally unknown receiver implementation (version), that can send smoothened RTT values, as well as not smoothened.

@maxsharabayko
Copy link
Collaborator

In some use cases the actual RTT value is more desired, than the smoothened one.
We should consider the receiver to send the instantaneous RTT back to the sender, because both sender and receiver can filter those values when required.

@maxsharabayko maxsharabayko added this to the v1.3.4 milestone Aug 1, 2019
@maxsharabayko maxsharabayko added the [core] Area: Changes in SRT library core label Aug 1, 2019
@smsajjadi
Copy link
Author

In some use cases the actual RTT value is more desired, than the smoothened one.
We should consider the receiver to send the instantaneous RTT back to the sender, because both sender and receiver can filter those values when required.

This makes sense. This way the RTT on both sides could be in sync

@jeandube
Copy link
Collaborator

jeandube commented Aug 1, 2019

I think RTT was smoothened in receiver (upon ACKACK reception) since UDT4 (or earlier). But I agree that the instant RTT can be helpfull for features such as Network Adaptive Encoding. But only the for the receive it is 'instant' The receiver will know it via the following ACK, which is can be long if a missing packet blocks the ACK progression. Maybe an alternative stats feedback though keepalive when needed can help.

@maxsharabayko
Copy link
Collaborator

@jeandube, you are right. The tricky part is that the receiver will calculate instant RTT based on the ACKACK packet from the sender. But will report this value only with the next ACK to the sender, which may happen up to 10 ms later. 🤔
Some congestion control algorithms also rely on the changes in instant RTT. So would be helpful if could be done with the exsisting packet exchange mechanism of SRT.

@maxsharabayko maxsharabayko removed this from the v1.3.4 milestone Aug 9, 2019
@oviano
Copy link
Contributor

oviano commented Aug 16, 2019

Think this is similar to this that I requested?

#665

@maxsharabayko
Copy link
Collaborator

There are several points.

  1. The receiver measures RTT, applies IIR filter, and sends the filtered value back to the sender. The sender filters this (already filteted) value again. Might be that the receiver is better to send the actual value of RTT, though with the next ACK, so delayed by (10 + RTT/2) ms. Then the sender will smoothen it anyway.
  2. Besides that still it would be good to determine the RTT on the sender side. Maybe a delay between sending a data packet and receiving ACK for it would be a good estimation, if 10 ms ACK sending period is taken into account.

Regarding #665, I thought you added saving latest RTT before the IIR filtering, and exposed it in SRT statistics. If I missed this, please correct me.

As Jean wrote,

I agree that the instant RTT can be helpfull for features such as Network Adaptive Encoding.

And that is instant RTT on the sender side. And the one it received from the receiver is already a bit delayed. Although may still be better to receive the actual value, instead of the smoothened one, and expose it in adfition to the smoothened.
So keep you changes for now. We will probably return to this discussion.

@mbakholdina
Copy link
Collaborator

mbakholdina commented Apr 23, 2021

An update on the current thread.

According to the latest UDT draft and UDT implementation, at the very beginning there was no smoothing on the sender side. The RTT and RTTVar values were taken from the ACK packets. I suppose that the main reason EWMA has been introduced on the sender side is the adding of bidirectional transmission in UDT. This can be indirectly confirmed by the following UDT article:

  • The RTT value should be sent back to the sender, e.g., in ACK. UDT does not transmit RTTVar to the peer side. The peer side will update its own RTT and RTTVar values using the same formula as above, in which case rtt is the most recent value it receives, e.g., carried by an incoming ACK.
  • Note 2.2: A UDT socket can both send and receive. RTT, RTTVar, and RTO are not just sender specific variables. They are shared by both the sender and the receiver (of the same socket). When a UDT socket receives data, it updates its local RTT and RTTVar, which can be used for its own sender as well.
  • Implementation Note 2.3: There is no need to calculate RTT and RTTVar in the same way as UDT does. If a protocol acknowledges immediately after receiving a data packet, RTT can be calculated by the difference between the ACK arrival time and the departure time of the corresponding data packet. In this case, there is no need to send ACK2.

On the SRT side, we've recently done some improvements around the RTT estimation, see PR #1957 (will be merged right after release v1.4.3). The detailed list of improvements is provided within the PR. One of them is to remove double smoothing at the sender side in case of unidirectional transmission. In this case, we now extract RTT and RTTVar values from the ACK packets. The RTT estimate (instantaneous) is calculated at the receiver side, then the EWMA is applied and smoothed RTT as well as RTTVar are sent to the receiver within ACK packets. There is no need to apply double smoothing on the sender side here plus the estimate is already "behind the time" at least by RTT/2. However, in the case of bidirectional transmission we still apply double smoothing as the most easiest way of obtaining RTT estimate. Improving this will require additional effort and research, out of scope currently.

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 Type: Maintenance Work required to maintain or clean up the code
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants