mirror of
https://github.com/transmission/transmission
synced 2024-12-26 09:37:56 +00:00
perf: reduce excess rand() calls in tr_bandwidth::phaseOne() (#4404)
This commit is contained in:
parent
128cf34123
commit
9e6ffa351c
1 changed files with 30 additions and 23 deletions
|
@ -4,7 +4,8 @@
|
|||
// License text can be found in the licenses/ folder.
|
||||
|
||||
#include <algorithm>
|
||||
#include <utility> // std::swap()
|
||||
#include <random> // for std::mt19937
|
||||
#include <utility> // for std::swap()
|
||||
#include <vector>
|
||||
|
||||
#include <fmt/core.h>
|
||||
|
@ -12,7 +13,6 @@
|
|||
#include "transmission.h"
|
||||
|
||||
#include "bandwidth.h"
|
||||
#include "crypto-utils.h" // tr_rand_int()
|
||||
#include "log.h"
|
||||
#include "peer-io.h"
|
||||
#include "tr-assert.h"
|
||||
|
@ -166,31 +166,38 @@ void tr_bandwidth::allocateBandwidth(
|
|||
|
||||
void tr_bandwidth::phaseOne(std::vector<tr_peerIo*>& peer_array, tr_direction dir)
|
||||
{
|
||||
/* First phase of IO. Tries to distribute bandwidth fairly to keep faster
|
||||
* peers from starving the others. Loop through the peers, giving each a
|
||||
* small chunk of bandwidth. Keep looping until we run out of bandwidth
|
||||
* and/or peers that can use it */
|
||||
// First phase of IO. Tries to distribute bandwidth fairly to keep faster
|
||||
// peers from starving the others.
|
||||
tr_logAddTrace(fmt::format("{} peers to go round-robin for {}", peer_array.size(), dir == TR_UP ? "upload" : "download"));
|
||||
|
||||
auto n = peer_array.size();
|
||||
while (n > 0)
|
||||
// Shuffle the peers so they all have equal chance to be first in line.
|
||||
thread_local auto random_engine = std::mt19937{ std::random_device{}() };
|
||||
std::shuffle(std::begin(peer_array), std::end(peer_array), random_engine);
|
||||
|
||||
// Give each peer `Increment` bandwidth bytes to use. Repeat this
|
||||
// process until we run out of bandwidth and/or peers that can use it.
|
||||
for (size_t n_unfinished = std::size(peer_array); n_unfinished > 0U;)
|
||||
{
|
||||
auto const i = tr_rand_int(n); /* pick a peer at random */
|
||||
|
||||
// value of 3000 bytes chosen so that when using µTP we'll send a full-size
|
||||
// frame right away and leave enough buffered data for the next frame to go
|
||||
// out in a timely manner.
|
||||
static auto constexpr Increment = size_t{ 3000 };
|
||||
|
||||
auto const bytes_used = peer_array[i]->flush(dir, Increment);
|
||||
|
||||
tr_logAddTrace(fmt::format("peer #{} of {} used {} bytes in this pass", i, n, bytes_used));
|
||||
|
||||
if (bytes_used != Increment)
|
||||
for (size_t i = 0; i < n_unfinished;)
|
||||
{
|
||||
// peer is done writing for now; move it to the end of the list
|
||||
std::swap(peer_array[i], peer_array[n - 1]);
|
||||
--n;
|
||||
// Value of 3000 bytes chosen so that when using µTP we'll send a full-size
|
||||
// frame right away and leave enough buffered data for the next frame to go
|
||||
// out in a timely manner.
|
||||
static auto constexpr Increment = size_t{ 3000 };
|
||||
|
||||
auto const bytes_used = peer_array[i]->flush(dir, Increment);
|
||||
tr_logAddTrace(fmt::format("peer #{} of {} used {} bytes in this pass", i, n_unfinished, bytes_used));
|
||||
|
||||
if (bytes_used != Increment)
|
||||
{
|
||||
// peer is done writing for now; move it to the end of the list
|
||||
std::swap(peer_array[i], peer_array[n_unfinished - 1]);
|
||||
--n_unfinished;
|
||||
}
|
||||
else
|
||||
{
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue