Skip to content

Commit 578d353

Browse files
committed
back-port fix request queue size performance issue
1 parent 112d75e commit 578d353

6 files changed

Lines changed: 62 additions & 16 deletions

File tree

‎ChangeLog‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
1.0.6 release
22

3+
* fix request queue size performance issue
34
* slightly improve UDP tracker performance
45
* fix http scrapes
56
* add missing port mapping functions to python binding

‎include/libtorrent/peer_connection.hpp‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -801,6 +801,12 @@ namespace libtorrent
801801
// other peers to compare it to.
802802
bool m_exceeded_limit:1;
803803

804+
// this is slow-start at the bittorrent layer. It affects how we increase
805+
// desired queue size (i.e. the number of outstanding requests we keep).
806+
// While the underlying transport protocol is in slow-start, the number of
807+
// outstanding requests need to increase at the same pace to keep up.
808+
bool m_slow_start:1;
809+
804810
// TODO: make these private as well
805811
protected:
806812

@@ -1025,6 +1031,12 @@ namespace libtorrent
10251031
// extended.
10261032
int m_timeout_extend;
10271033

1034+
// the number of payload bytes downloaded last second tick
1035+
boost::int32_t m_downloaded_last_second;
1036+
1037+
// the number of payload bytes uploaded last second tick
1038+
boost::int32_t m_uploaded_last_second;
1039+
10281040
// the number of bytes that the other
10291041
// end has to send us in order to respond
10301042
// to all outstanding piece requests we
@@ -1147,6 +1159,7 @@ namespace libtorrent
11471159

11481160
// the number of request we should queue up
11491161
// at the remote end.
1162+
// TODO: 2 rename this target queue size
11501163
boost::uint16_t m_desired_queue_size;
11511164

11521165
#ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES

‎src/peer_connection.cpp‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2320,6 +2320,10 @@ namespace libtorrent
23202320
if (!m_bitfield_received) incoming_have_none();
23212321
if (is_disconnecting()) return;
23222322

2323+
// slow-start
2324+
if (m_slow_start)
2325+
m_desired_queue_size += 1;
2326+
23232327
update_desired_queue_size();
23242328

23252329
#ifndef TORRENT_DISABLE_EXTENSIONS
@@ -4320,6 +4324,17 @@ namespace libtorrent
43204324
m_ignore_bandwidth_limits = m_ses.settings().ignore_limits_on_local_network
43214325
&& on_local_network();
43224326

4327+
// if our download rate isn't increasing significantly anymore, end slow
4328+
// start. The 10kB is to have some slack here.
4329+
if (m_slow_start && m_downloaded_last_second > 0
4330+
&& m_downloaded_last_second + 10000
4331+
>= m_statistics.last_payload_downloaded())
4332+
{
4333+
m_slow_start = false;
4334+
}
4335+
m_downloaded_last_second = m_statistics.last_payload_downloaded();
4336+
m_uploaded_last_second = m_statistics.last_payload_uploaded();
4337+
43234338
m_statistics.second_tick(tick_interval_ms);
43244339

43254340
if (m_statistics.upload_payload_rate() > m_upload_rate_peak)

‎src/session.cpp‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1385,7 +1385,7 @@ namespace libtorrent
13851385
, connections_limit(200)
13861386
, connections_slack(10)
13871387
, utp_target_delay(100) // milliseconds
1388-
, utp_gain_factor(1500) // bytes per rtt
1388+
, utp_gain_factor(3000) // bytes per rtt
13891389
, utp_min_timeout(500) // milliseconds
13901390
, utp_syn_resends(2)
13911391
, utp_fin_resends(2)

‎src/utp_stream.cpp‎

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -623,7 +623,7 @@ struct utp_socket_impl
623623
// this is done at startup of a socket in order to find its
624624
// link capacity faster. This behaves similar to TCP slow start
625625
bool m_slow_start:1;
626-
626+
627627
// this is true as long as we have as many packets in
628628
// flight as allowed by the congestion window (cwnd)
629629
bool m_cwnd_full:1;
@@ -1602,7 +1602,9 @@ struct holder
16021602
// congestion window, false if there is no more space.
16031603
bool utp_socket_impl::send_pkt(int flags)
16041604
{
1605+
#ifdef TORRENT_EXPENSIVE_INVARIANT_CHECKS
16051606
INVARIANT_CHECK;
1607+
#endif
16061608

16071609
bool force = (flags & pkt_ack) || (flags & pkt_fin);
16081610

@@ -2144,29 +2146,33 @@ void utp_socket_impl::experienced_loss(int seq_nr)
21442146
// less than or equal to. If we experience loss of the
21452147
// same packet again, ignore it.
21462148
if (compare_less_wrap(seq_nr, m_loss_seq_nr + 1, ACK_MASK)) return;
2147-
2149+
2150+
// cut window size in 2
2151+
m_cwnd = (std::max)(m_cwnd * m_sm->loss_multiplier() / 100, boost::int64_t(m_mtu << 16));
2152+
m_loss_seq_nr = m_seq_nr;
2153+
UTP_LOGV("%8p: Lost packet %d caused cwnd cut\n", this, seq_nr);
2154+
21482155
// if we happen to be in slow-start mode, we need to leave it
2156+
// note that we set ssthres to the window size _after_ reducing it. Next slow
2157+
// start should end before we over shoot.
21492158
if (m_slow_start)
21502159
{
21512160
m_ssthres = m_cwnd >> 16;
21522161
m_slow_start = false;
21532162
UTP_LOGV("%8p: experienced loss, slow_start -> 0\n", this);
21542163
}
21552164

2156-
// cut window size in 2
2157-
m_cwnd = (std::max)(m_cwnd * m_sm->loss_multiplier() / 100, boost::int64_t(m_mtu << 16));
2158-
m_loss_seq_nr = m_seq_nr;
2159-
UTP_LOGV("%8p: Lost packet %d caused cwnd cut\n", this, seq_nr);
2160-
21612165
// the window size could go below one MMS here, if it does,
21622166
// we'll get a timeout in about one second
2163-
2167+
21642168
m_sm->inc_stats_counter(utp_socket_manager::packet_loss);
21652169
}
21662170

21672171
void utp_socket_impl::maybe_inc_acked_seq_nr()
21682172
{
2173+
#ifdef TORRENT_EXPENSIVE_INVARIANT_CHECKS
21692174
INVARIANT_CHECK;
2175+
#endif
21702176

21712177
bool incremented = false;
21722178
// don't pass m_seq_nr, since we move into sequence
@@ -2198,7 +2204,9 @@ void utp_socket_impl::maybe_inc_acked_seq_nr()
21982204
void utp_socket_impl::ack_packet(packet* p, ptime const& receive_time
21992205
, boost::uint32_t& min_rtt, boost::uint16_t seq_nr)
22002206
{
2207+
#ifdef TORRENT_EXPENSIVE_INVARIANT_CHECKS
22012208
INVARIANT_CHECK;
2209+
#endif
22022210

22032211
TORRENT_ASSERT(p);
22042212

@@ -2244,7 +2252,9 @@ void utp_socket_impl::ack_packet(packet* p, ptime const& receive_time
22442252

22452253
void utp_socket_impl::incoming(boost::uint8_t const* buf, int size, packet* p, ptime now)
22462254
{
2255+
#ifdef TORRENT_EXPENSIVE_INVARIANT_CHECKS
22472256
INVARIANT_CHECK;
2257+
#endif
22482258

22492259
while (!m_read_buffer.empty())
22502260
{
@@ -3213,7 +3223,7 @@ void utp_socket_impl::do_ledbat(int acked_bytes, int delay, int in_flight, ptime
32133223
boost::int64_t window_factor = (boost::int64_t(acked_bytes) << 16) / in_flight;
32143224
boost::int64_t delay_factor = (boost::int64_t(target_delay - delay) << 16) / target_delay;
32153225
boost::int64_t scaled_gain;
3216-
3226+
32173227
if (delay >= target_delay)
32183228
{
32193229
if (m_slow_start)
@@ -3502,15 +3512,15 @@ void utp_socket_impl::check_receive_buffers() const
35023512
void utp_socket_impl::check_invariant() const
35033513
{
35043514
for (int i = m_outbuf.cursor();
3505-
i != int((m_outbuf.cursor() + m_outbuf.span()) & ACK_MASK);
3515+
i != int((m_outbuf.cursor() + m_outbuf.span()) & ACK_MASK);
35063516
i = (i + 1) & ACK_MASK)
35073517
{
35083518
packet* p = (packet*)m_outbuf.at(i);
3509-
if (m_mtu_seq == i && m_mtu_seq != 0 && p)
3519+
if (!p) continue;
3520+
if (m_mtu_seq == i && m_mtu_seq != 0)
35103521
{
35113522
TORRENT_ASSERT(p->mtu_probe);
35123523
}
3513-
if (!p) continue;
35143524
TORRENT_ASSERT(((utp_header*)p->buf)->seq_nr == i);
35153525
}
35163526

‎tools/parse_utp_log.py‎

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,10 @@
5353
delay_base = 'steps lw 2 lc rgb "purple"'
5454
target_delay = 'steps lw 2 lc rgb "red"'
5555
off_target = 'dots lc rgb "blue"'
56-
cwnd = 'steps lc rgb "green"'
56+
cwnd = 'steps lc rgb "green" lw 2'
5757
window_size = 'steps lc rgb "sea-green"'
5858
rtt = 'lines lc rgb "light-blue"'
59+
send_buffer = 'lines lc rgb "light-red"'
5960

6061
metrics = {
6162
'our_delay':['our delay (ms)', 'x1y2', delay_samples],
@@ -77,7 +78,7 @@
7778
'their_delay_base':['their delay base (us)', 'x1y1', delay_base],
7879
'their_actual_delay':['their actual delay (us)', 'x1y1', delay_samples],
7980
'actual_delay':['actual_delay (us)', 'x1y1', delay_samples],
80-
'send_buffer':['send buffer size (B)', 'x1y1', 'lines'],
81+
'send_buffer':['send buffer size (B)', 'x1y1', send_buffer],
8182
'recv_buffer':['receive buffer size (B)', 'x1y1', 'lines']
8283
}
8384

@@ -199,11 +200,17 @@
199200

200201
plot = [
201202
{
202-
'data': ['upload_rate', 'max_window', 'cur_window', 'wnduser', 'cur_window_packets', 'packet_size', 'rtt'],
203+
'data': ['max_window', 'send_buffer', 'cur_window', 'rtt'],
203204
'title': 'send-packet-size',
204205
'y1': 'Bytes',
205206
'y2': 'Time (ms)'
206207
},
208+
{
209+
'data': ['upload_rate', 'max_window', 'cur_window', 'wnduser', 'cur_window_packets', 'packet_size', 'rtt'],
210+
'title': 'slow-start',
211+
'y1': 'Bytes',
212+
'y2': 'Time (ms)'
213+
},
207214
{
208215
'data': ['max_window', 'cur_window', 'our_delay', 'target_delay', 'ssthres'],
209216
'title': 'cwnd',

0 commit comments

Comments
 (0)