Open GoogleCodeExporter opened 8 years ago
one way to speed it up would be to consolidate all the slow calls to
auto_managed(), make those calls back-to-back first, then make all the calls to
change the state (which are non-blocking).
Is there any way to avoid the blocking call at all? If you're pausing all
torrents for instance, I would imagine that you just want to call
auto_managed(false) and pause().
I can imagine that if you just have a toggle function, you would need to query
the current state first. Is that the case?
anyway, if you make all the non-blocking, state-changing calls back-to-back,
libtorrent will be able to defer the call to
recalculate_auto_managed_torrents() more more efficiently, to just call that
once or twice.
Original comment by arvid.no...@gmail.com
on 17 Nov 2014 at 6:15
btw. I assumed that you are referring to the auto_managed() overload that does
not take any arguments, which queries the current state of the torrent.
The overload that takes a bool and _sets_ the state, is still fast, right?
Original comment by arvid.no...@gmail.com
on 17 Nov 2014 at 6:18
> I assumed that you are referring to the auto_managed() overload that does not
take any arguments, which queries the current state of the torrent.
No, sorry. I was talking about overload auto_managed(bool). This overload
itself is fast, but it queues recalculate_auto_managed_torrents() which is
slow. After every (fast) call auto_managed(bool), libtorrent does a (slow)
recalculate_auto_managed_torrents process. And at that time if we do blocking
call to libtorrent UI would hang.
We do blocking UI mostly because of issue #684. But even if we don't. Having
libtorrent busy for a long time is bad. If libtorrent thread is busy, and if
some action does a blocking call, UI will still hang.
I think there are two way to solve the problem:
1. Make recalculate_auto_managed_torrents incremental. So it does little work,
if only one torrent is changed.
2. Coalesce many sequential recalculate_auto_managed_torrents into one. In that
case perhaps we need a call to set auto_managed flag on many torrents at once.
I like the first solution more.
Original comment by vanya...@gmail.com
on 17 Nov 2014 at 10:51
right. currently libtorrent implements (2), so I guess there's a bug somewhere.
There is a trade-off between coalescing more events and having low latency.
Currently, latency is favored. When the network thread receives the command to
pause a torrent it posts another message onto its queue which will trigger the
recalculate auto-managed. Everything that's already on the queue will hence be
executed first before recalculate is called.
However, if you have any ping-pong dependencies where you wait for libtorrent
in between the calls, then you'll get poor performance.
Original comment by arvid.no...@gmail.com
on 17 Nov 2014 at 5:39
> if you have any ping-pong dependencies where you wait for libtorrent in
between the calls, then you'll get poor performance.
That is the case. Looking at profile
https://cloud.githubusercontent.com/assets/286877/5059717/bb905a06-6d37-11e4-809
f-86785bd9aa6a.png qbittorrent calls torrent_handle::info_hash() in between
auto_managed() calls.
But even if there was no info_hash() calls. As I understand
boost::asio::io_service is FIFO, so if there is queued call to
session_impl::on_trigger_auto_manage(), torrent::auto_managed(bool) won't be
executed before session_impl::on_trigger_auto_manage() finishes it work.
Original comment by vanya...@gmail.com
on 18 Nov 2014 at 3:06
I did commit that patch to make info_hash() fast. Do you know if there are any
other blocking calls made in between the calls to auto_managed(bool)?
What would be run on the network thread is probably:
auto_managed(bool) -> post recalculate_auto_managed()
recalculate_auto_managed() (takes a long time, during this time the qbt thread
posts all the remaining auto_managed(bool) calls)
auto_managed(bool) -> post recalculate_auto_managed(), but this is at the end
of the queue, and won't get executed until all remaining auto_managed(bool)
have been executed.
Original comment by arvid.no...@gmail.com
on 18 Nov 2014 at 10:00
> What would be run on the network thread is probably:
> auto_managed(bool) -> post recalculate_auto_managed()
> recalculate_auto_managed() (takes a long time, during this time the qbt
> thread posts all the remaining auto_managed(bool) calls)
> auto_managed(bool) -> post recalculate_auto_managed(), but this is at
> the end of the queue, and won't get executed until all remaining
> auto_managed(bool) have been executed.
I thought about that a bit. Yes you are right this should help. I'll test this.
Thank you.
Original comment by vanya...@gmail.com
on 19 Nov 2014 at 8:57
Original issue reported on code.google.com by
vanya...@gmail.com
on 16 Nov 2014 at 1:01