added more detailed instrumentation of the disk I/O thread
This commit is contained in:
parent
fdb68ab784
commit
a942890e8d
|
@ -16,6 +16,7 @@
|
||||||
* support for BitTyrant choker algorithm
|
* support for BitTyrant choker algorithm
|
||||||
* support for automatically start torrents when they receive an
|
* support for automatically start torrents when they receive an
|
||||||
incoming connection
|
incoming connection
|
||||||
|
* added more detailed instrumentation of the disk I/O thread
|
||||||
|
|
||||||
0.15 release
|
0.15 release
|
||||||
|
|
||||||
|
|
|
@ -820,6 +820,9 @@ Returns status of the disk cache for this session.
|
||||||
int cache_size;
|
int cache_size;
|
||||||
int read_cache_size;
|
int read_cache_size;
|
||||||
int total_used_buffers;
|
int total_used_buffers;
|
||||||
|
int average_queue_time;
|
||||||
|
int average_read_time;
|
||||||
|
int job_queue_length;
|
||||||
};
|
};
|
||||||
|
|
||||||
``blocks_written`` is the total number of 16 KiB blocks written to disk
|
``blocks_written`` is the total number of 16 KiB blocks written to disk
|
||||||
|
@ -849,6 +852,14 @@ This includes both read and write cache.
|
||||||
This includes the read/write disk cache as well as send and receive buffers
|
This includes the read/write disk cache as well as send and receive buffers
|
||||||
used in peer connections.
|
used in peer connections.
|
||||||
|
|
||||||
|
``average_queue_time`` is the number of microseconds an average disk I/O job
|
||||||
|
has to wait in the job queue before it get processed.
|
||||||
|
|
||||||
|
``average_read_time`` is the number of microseconds a read job takes to
|
||||||
|
wait in the queue and complete, in microseconds.
|
||||||
|
|
||||||
|
``job_queue_length`` is the number of jobs in the job queue.
|
||||||
|
|
||||||
get_cache_info()
|
get_cache_info()
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "libtorrent/storage.hpp"
|
#include "libtorrent/storage.hpp"
|
||||||
#include "libtorrent/allocator.hpp"
|
#include "libtorrent/allocator.hpp"
|
||||||
#include "libtorrent/io_service.hpp"
|
#include "libtorrent/io_service.hpp"
|
||||||
|
#include "libtorrent/sliding_average.hpp"
|
||||||
|
|
||||||
#include <boost/function/function0.hpp>
|
#include <boost/function/function0.hpp>
|
||||||
#include <boost/function/function2.hpp>
|
#include <boost/function/function2.hpp>
|
||||||
|
@ -140,6 +141,10 @@ namespace libtorrent
|
||||||
|
|
||||||
// this is called when operation completes
|
// this is called when operation completes
|
||||||
boost::function<void(int, disk_io_job const&)> callback;
|
boost::function<void(int, disk_io_job const&)> callback;
|
||||||
|
|
||||||
|
// the time when this job was issued. This is used to
|
||||||
|
// keep track of disk I/O congestion
|
||||||
|
ptime start_time;
|
||||||
};
|
};
|
||||||
|
|
||||||
// returns true if the fundamental operation
|
// returns true if the fundamental operation
|
||||||
|
@ -189,6 +194,11 @@ namespace libtorrent
|
||||||
// the total number of blocks that are currently in use
|
// the total number of blocks that are currently in use
|
||||||
// this includes send and receive buffers
|
// this includes send and receive buffers
|
||||||
mutable int total_used_buffers;
|
mutable int total_used_buffers;
|
||||||
|
|
||||||
|
// times in microseconds
|
||||||
|
int average_queue_time;
|
||||||
|
int average_read_time;
|
||||||
|
int job_queue_length;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TORRENT_EXPORT disk_buffer_pool : boost::noncopyable
|
struct TORRENT_EXPORT disk_buffer_pool : boost::noncopyable
|
||||||
|
@ -408,6 +418,12 @@ namespace libtorrent
|
||||||
// exceed m_cache_size
|
// exceed m_cache_size
|
||||||
cache_status m_cache_stats;
|
cache_status m_cache_stats;
|
||||||
|
|
||||||
|
// keeps average queue time for disk jobs (in microseconds)
|
||||||
|
sliding_average m_queue_time;
|
||||||
|
|
||||||
|
// average read time for cache misses (in microseconds)
|
||||||
|
sliding_average m_read_time;
|
||||||
|
|
||||||
#ifdef TORRENT_DISK_STATS
|
#ifdef TORRENT_DISK_STATS
|
||||||
std::ofstream m_log;
|
std::ofstream m_log;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -0,0 +1,70 @@
|
||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (c) 2010, Arvid Norberg
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in
|
||||||
|
the documentation and/or other materials provided with the distribution.
|
||||||
|
* Neither the name of the author nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived
|
||||||
|
from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace libtorrent
|
||||||
|
{
|
||||||
|
// a sliding average accumulator. Add samples to it and it
|
||||||
|
// keeps track of a sliding mean value and an average deviation
|
||||||
|
// from that average.
|
||||||
|
struct sliding_average
|
||||||
|
{
|
||||||
|
sliding_average(): m_mean(-1), m_average_deviation(-1) {}
|
||||||
|
|
||||||
|
void add_sample(int s)
|
||||||
|
{
|
||||||
|
if (m_mean == -1)
|
||||||
|
{
|
||||||
|
m_mean = s;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int deviation = abs(m_mean - s);
|
||||||
|
|
||||||
|
m_mean = m_mean - m_mean / 16 + s / 16;
|
||||||
|
|
||||||
|
if (m_average_deviation == -1)
|
||||||
|
{
|
||||||
|
m_average_deviation = deviation;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_average_deviation = m_average_deviation - m_average_deviation / 16 + deviation / 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mean() const { return m_mean != -1 ? m_mean : 0; }
|
||||||
|
int avg_deviation() const { return m_average_deviation != -1 ? m_average_deviation : 0; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
int m_mean;
|
||||||
|
int m_average_deviation;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -362,7 +362,14 @@ namespace libtorrent
|
||||||
mutex::scoped_lock l(m_piece_mutex);
|
mutex::scoped_lock l(m_piece_mutex);
|
||||||
m_cache_stats.total_used_buffers = in_use();
|
m_cache_stats.total_used_buffers = in_use();
|
||||||
m_cache_stats.queued_bytes = m_queue_buffer_size;
|
m_cache_stats.queued_bytes = m_queue_buffer_size;
|
||||||
return m_cache_stats;
|
|
||||||
|
cache_status ret = m_cache_stats;
|
||||||
|
|
||||||
|
ret.average_queue_time = m_queue_time.mean();
|
||||||
|
ret.average_read_time = m_read_time.mean();
|
||||||
|
ret.job_queue_length = m_jobs.size();
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// aborts read operations
|
// aborts read operations
|
||||||
|
@ -1315,6 +1322,7 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
m_jobs.push_back(j);
|
m_jobs.push_back(j);
|
||||||
m_jobs.back().callback.swap(const_cast<boost::function<void(int, disk_io_job const&)>&>(f));
|
m_jobs.back().callback.swap(const_cast<boost::function<void(int, disk_io_job const&)>&>(f));
|
||||||
|
m_jobs.back().start_time = time_now_hires();
|
||||||
|
|
||||||
if (j.action == disk_io_job::write)
|
if (j.action == disk_io_job::write)
|
||||||
m_queue_buffer_size += j.buffer_size;
|
m_queue_buffer_size += j.buffer_size;
|
||||||
|
@ -1591,6 +1599,9 @@ namespace libtorrent
|
||||||
if (j.storage && j.storage->get_storage_impl()->m_settings == 0)
|
if (j.storage && j.storage->get_storage_impl()->m_settings == 0)
|
||||||
j.storage->get_storage_impl()->m_settings = &m_settings;
|
j.storage->get_storage_impl()->m_settings = &m_settings;
|
||||||
|
|
||||||
|
ptime now = time_now_hires();
|
||||||
|
m_queue_time.add_sample(total_microseconds(now - j.start_time));
|
||||||
|
|
||||||
switch (j.action)
|
switch (j.action)
|
||||||
{
|
{
|
||||||
case disk_io_job::update_settings:
|
case disk_io_job::update_settings:
|
||||||
|
@ -2216,6 +2227,8 @@ namespace libtorrent
|
||||||
&& j.buffer != 0)
|
&& j.buffer != 0)
|
||||||
rename_buffer(j.buffer, "posted send buffer");
|
rename_buffer(j.buffer, "posted send buffer");
|
||||||
#endif
|
#endif
|
||||||
|
ptime now = time_now_hires();
|
||||||
|
m_read_time.add_sample(total_microseconds(now - j.start_time));
|
||||||
post_callback(j.callback, j, ret);
|
post_callback(j.callback, j, ret);
|
||||||
#ifndef BOOST_NO_EXCEPTIONS
|
#ifndef BOOST_NO_EXCEPTIONS
|
||||||
} catch (std::exception&)
|
} catch (std::exception&)
|
||||||
|
|
Loading…
Reference in New Issue