-
-
Notifications
You must be signed in to change notification settings - Fork 1k
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
A few optimizations to lower CPU usage #7898
base: RC_2_0
Are you sure you want to change the base?
Changes from 4 commits
16caed4
a535e70
9e59b89
e6b3eae
b7890d8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
@@ -2922,7 +2922,7 @@ namespace { | |||||||||
for (auto& aep : aeps) | ||||||||||
{ | ||||||||||
if (aep.socket != s) continue; | ||||||||||
std::swap(aeps[valid_endpoints], aep); | ||||||||||
if (&aeps[valid_endpoints] != &aep) std::swap(aeps[valid_endpoints], aep); | ||||||||||
valid_endpoints++; | ||||||||||
return; | ||||||||||
} | ||||||||||
|
@@ -3114,14 +3114,16 @@ namespace { | |||||||||
// so that each one should get at least one announce | ||||||||||
std::vector<announce_state> listen_socket_states; | ||||||||||
|
||||||||||
bool announce_to_all_tiers = settings().get_bool(settings_pack::announce_to_all_tiers); | ||||||||||
bool announce_to_all_trackers = settings().get_bool(settings_pack::announce_to_all_trackers); | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure about this repo policy on
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Whoops, I'm used to rust, where things are const by default. |
||||||||||
#ifndef TORRENT_DISABLE_LOGGING | ||||||||||
int idx = -1; | ||||||||||
if (should_log()) | ||||||||||
{ | ||||||||||
debug_log("*** announce: " | ||||||||||
"[ announce_to_all_tiers: %d announce_to_all_trackers: %d num_trackers: %d ]" | ||||||||||
, settings().get_bool(settings_pack::announce_to_all_tiers) | ||||||||||
, settings().get_bool(settings_pack::announce_to_all_trackers) | ||||||||||
, announce_to_all_tiers | ||||||||||
, announce_to_all_trackers | ||||||||||
, int(m_trackers.size())); | ||||||||||
} | ||||||||||
#endif | ||||||||||
|
@@ -3195,24 +3197,24 @@ namespace { | |||||||||
} | ||||||||||
#endif | ||||||||||
|
||||||||||
if (settings().get_bool(settings_pack::announce_to_all_tiers) | ||||||||||
&& !settings().get_bool(settings_pack::announce_to_all_trackers) | ||||||||||
if (announce_to_all_tiers | ||||||||||
&& !announce_to_all_trackers | ||||||||||
&& state.sent_announce | ||||||||||
&& ae.tier <= state.tier | ||||||||||
&& state.tier != INT_MAX) | ||||||||||
continue; | ||||||||||
|
||||||||||
if (ae.tier > state.tier && state.sent_announce | ||||||||||
&& !settings().get_bool(settings_pack::announce_to_all_tiers)) continue; | ||||||||||
&& !announce_to_all_tiers) continue; | ||||||||||
if (a.is_working()) { state.tier = ae.tier; state.sent_announce = false; } | ||||||||||
if (!a.can_announce(now, is_seed(), ae.fail_limit)) | ||||||||||
{ | ||||||||||
// this counts | ||||||||||
if (a.is_working()) | ||||||||||
{ | ||||||||||
state.sent_announce = true; | ||||||||||
if (!settings().get_bool(settings_pack::announce_to_all_trackers) | ||||||||||
&& !settings().get_bool(settings_pack::announce_to_all_tiers)) | ||||||||||
if (!announce_to_all_trackers | ||||||||||
&& !announce_to_all_tiers) | ||||||||||
{ | ||||||||||
state.done = true; | ||||||||||
} | ||||||||||
|
@@ -3289,8 +3291,8 @@ namespace { | |||||||||
|
||||||||||
state.sent_announce = true; | ||||||||||
if (a.is_working() | ||||||||||
&& !settings().get_bool(settings_pack::announce_to_all_trackers) | ||||||||||
&& !settings().get_bool(settings_pack::announce_to_all_tiers)) | ||||||||||
&& !announce_to_all_trackers | ||||||||||
&& !announce_to_all_tiers) | ||||||||||
{ | ||||||||||
state.done = true; | ||||||||||
} | ||||||||||
|
@@ -9901,16 +9903,18 @@ namespace { | |||||||||
|
||||||||||
time_point32 next_announce = time_point32::max(); | ||||||||||
|
||||||||||
std::vector<timer_state> listen_socket_states; | ||||||||||
std::map<std::weak_ptr<aux::listen_socket_t>, timer_state, std::owner_less<std::weak_ptr<aux::listen_socket_t>>> listen_socket_states; | ||||||||||
|
||||||||||
bool announce_to_all_tiers = settings().get_bool(settings_pack::announce_to_all_tiers); | ||||||||||
bool announce_to_all_trackers = settings().get_bool(settings_pack::announce_to_all_trackers); | ||||||||||
#ifndef TORRENT_DISABLE_LOGGING | ||||||||||
int idx = -1; | ||||||||||
if (should_log()) | ||||||||||
{ | ||||||||||
debug_log("*** update_tracker_timer: " | ||||||||||
"[ announce_to_all_tiers: %d announce_to_all_trackers: %d num_trackers: %d ]" | ||||||||||
, settings().get_bool(settings_pack::announce_to_all_tiers) | ||||||||||
, settings().get_bool(settings_pack::announce_to_all_trackers) | ||||||||||
, announce_to_all_tiers | ||||||||||
, announce_to_all_trackers | ||||||||||
, int(m_trackers.size())); | ||||||||||
} | ||||||||||
#endif | ||||||||||
|
@@ -9921,14 +9925,12 @@ namespace { | |||||||||
#endif | ||||||||||
for (auto const& aep : t.endpoints) | ||||||||||
{ | ||||||||||
auto aep_state_iter = std::find_if(listen_socket_states.begin(), listen_socket_states.end() | ||||||||||
, [&](timer_state const& s) { return s.socket == aep.socket; }); | ||||||||||
auto aep_state_iter = listen_socket_states.find(aep.socket.get_ptr()); | ||||||||||
if (aep_state_iter == listen_socket_states.end()) | ||||||||||
{ | ||||||||||
listen_socket_states.emplace_back(aep.socket); | ||||||||||
aep_state_iter = listen_socket_states.end() - 1; | ||||||||||
aep_state_iter = listen_socket_states.insert({aep.socket.get_ptr(), timer_state(aep.socket)}).first; | ||||||||||
} | ||||||||||
timer_state& ep_state = *aep_state_iter; | ||||||||||
timer_state& ep_state = aep_state_iter->second; | ||||||||||
|
||||||||||
if (!aep.enabled) continue; | ||||||||||
for (protocol_version const ih : all_versions) | ||||||||||
|
@@ -9952,16 +9954,16 @@ namespace { | |||||||||
} | ||||||||||
#endif | ||||||||||
|
||||||||||
if (settings().get_bool(settings_pack::announce_to_all_tiers) | ||||||||||
&& !settings().get_bool(settings_pack::announce_to_all_trackers) | ||||||||||
if (announce_to_all_tiers | ||||||||||
&& !announce_to_all_trackers | ||||||||||
&& state.found_working | ||||||||||
&& t.tier <= state.tier | ||||||||||
&& state.tier != INT_MAX) | ||||||||||
continue; | ||||||||||
|
||||||||||
if (t.tier > state.tier) | ||||||||||
{ | ||||||||||
if (!settings().get_bool(settings_pack::announce_to_all_tiers)) break; | ||||||||||
if (!announce_to_all_tiers) break; | ||||||||||
state.found_working = false; | ||||||||||
} | ||||||||||
state.tier = t.tier; | ||||||||||
|
@@ -9978,17 +9980,17 @@ namespace { | |||||||||
} | ||||||||||
if (a.is_working()) state.found_working = true; | ||||||||||
if (state.found_working | ||||||||||
&& !settings().get_bool(settings_pack::announce_to_all_trackers) | ||||||||||
&& !settings().get_bool(settings_pack::announce_to_all_tiers)) | ||||||||||
&& !announce_to_all_trackers | ||||||||||
&& !announce_to_all_tiers) | ||||||||||
state.done = true; | ||||||||||
} | ||||||||||
} | ||||||||||
|
||||||||||
if (std::all_of(listen_socket_states.begin(), listen_socket_states.end() | ||||||||||
, [supports_protocol](timer_state const& s) { | ||||||||||
, [supports_protocol](std::pair<std::weak_ptr<aux::listen_socket_t>, timer_state> const& s) { | ||||||||||
for (protocol_version const ih : all_versions) | ||||||||||
{ | ||||||||||
if (supports_protocol[ih] && !s.state[ih].done) | ||||||||||
if (supports_protocol[ih] && !s.second.state[ih].done) | ||||||||||
return false; | ||||||||||
} | ||||||||||
return true; | ||||||||||
|
@@ -12310,7 +12312,10 @@ namespace { | |||||||||
{ | ||||||||||
announce_with_tracker(r.event); | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if this call fails, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
In all cases where |
||||||||||
} | ||||||||||
update_tracker_timer(aux::time_now32()); | ||||||||||
else | ||||||||||
{ | ||||||||||
update_tracker_timer(aux::time_now32()); | ||||||||||
} | ||||||||||
} | ||||||||||
|
||||||||||
#ifndef TORRENT_DISABLE_LOGGING | ||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure my concerns are valid but anyway:
1024
would suffice for most cases. Also this implies it needs some kind of cache replacement policy, for example LRU. Maybe libtorrent/boost provides such container?static
means it will be shared across all libtorrent sessions which isn't ideal either. It should be local to a specific torrent/session or whatever scope that make sense.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
std::unordered_map
's overhead, and even 1024 urls should be only ~40kb.2 & 3. I hadn't considered multiple threads, but I think I could just use
thread_local
instead ofstatic
.I think we could get rid of this cache if
announce_entry
stored the result ofis_i2p_url
along with it's url, although I'm not sure if that could be added, since it looks likeannounce_entry
is part of the ABI.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this cache is the only controversial part of this patch. It seems more natural to record whether a tracker is i2p or not once, and not call this function repeatedly. It's only 1 bit of information.
The ABI issue is a challenge though. in
master
the announce entries have been separated into internal and exported types, so it's easy to add internal fields without affecting the ABIThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since it's only one bit, could it be put in padding, like
verified
? Or could that cause some issues?