diff --git a/ChangeLog b/ChangeLog index ffa3434e6..614b898f4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,4 @@ + * rate limiter optimization * rate limiter overflow fix (for very high limits) * non-auto-managed torrents no longer count against the torrent limits * handle DHT error responses correctly diff --git a/include/libtorrent/bandwidth_limit.hpp b/include/libtorrent/bandwidth_limit.hpp index bc6c61926..8b1565f08 100644 --- a/include/libtorrent/bandwidth_limit.hpp +++ b/include/libtorrent/bandwidth_limit.hpp @@ -64,6 +64,19 @@ struct TORRENT_EXTRA_EXPORT bandwidth_channel void return_quota(int amount); void use_quota(int amount); + // this is an optimization. If there is more than one second + // of quota built up in this channel, just apply it right away + // instead of introducing a delay to split it up evenly. This + // should especially help in situations where a single peer + // has a capacity under the rate limit, but would otherwise be + // held back by the latency of getting bandwidth from the limiter + bool need_queueing(int amount) + { + if (m_quota_left - amount < m_limit) return true; + m_quota_left -= amount; + return false; + } + // used as temporary storage while distributing // bandwidth int tmp; diff --git a/src/bandwidth_manager.cpp b/src/bandwidth_manager.cpp index 6b36607cc..7b6f648c9 100644 --- a/src/bandwidth_manager.cpp +++ b/src/bandwidth_manager.cpp @@ -102,11 +102,17 @@ namespace libtorrent bw_request bwr(peer, blk, priority); int i = 0; - if (chan1 && chan1->throttle() > 0) bwr.channel[i++] = chan1; - if (chan2 && chan2->throttle() > 0) bwr.channel[i++] = chan2; - if (chan3 && chan3->throttle() > 0) bwr.channel[i++] = chan3; - if (chan4 && chan4->throttle() > 0) bwr.channel[i++] = chan4; - if (chan5 && chan5->throttle() > 0) bwr.channel[i++] = chan5; + if (chan1 && chan1->throttle() > 0 && chan1->need_queueing(blk)) + bwr.channel[i++] = chan1; + if (chan2 && chan2->throttle() > 0 && chan2->need_queueing(blk)) + bwr.channel[i++] = chan2; + if (chan3 && chan3->throttle() > 0 && chan3->need_queueing(blk)) + bwr.channel[i++] = chan3; + if (chan4 && chan4->throttle() > 0 && chan4->need_queueing(blk)) + bwr.channel[i++] = chan4; + if (chan5 && chan5->throttle() > 0 && chan5->need_queueing(blk)) + bwr.channel[i++] = chan5; + if (i == 0) { // the connection is not rate limited by any of its @@ -115,6 +121,7 @@ namespace libtorrent // the queue, just satisfy the request immediately return blk; } + m_queued_bytes += blk; m_queue.push_back(bwr); return 0;