~ubuntu-branches/ubuntu/maverick/libtorrent-rasterbar/maverick

« back to all changes in this revision

Viewing changes to docs/tuning.html

  • Committer: Bazaar Package Importer
  • Author(s): Christophe Sauthier
  • Date: 2010-08-10 12:59:37 UTC
  • mfrom: (1.3.7 upstream)
  • Revision ID: james.westby@ubuntu.com-20100810125937-jbcmmf17y8yo9hgz
Tags: 0.15.0-0ubuntu1
* New upstream version.
* debian/patches/100_fix_html_docs.patch: refreshed.
* debian/control: bump up standards-version to 3.9.1 (no changes).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?xml version="1.0" encoding="utf-8" ?>
 
2
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
3
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 
4
<head>
 
5
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 
6
<meta name="generator" content="Docutils 0.5: http://docutils.sourceforge.net/" />
 
7
<title>libtorrent manual</title>
 
8
<meta name="author" content="Arvid Norberg, arvid&#64;rasterbar.com" />
 
9
<link rel="stylesheet" type="text/css" href="../../css/base.css" />
 
10
<link rel="stylesheet" type="text/css" href="../../css/rst.css" />
 
11
<link rel="stylesheet" href="style.css" type="text/css" />
 
12
<style type="text/css">
 
13
/* Hides from IE-mac \*/
 
14
* html pre { height: 1%; }
 
15
/* End hide from IE-mac */
 
16
</style>
 
17
</head>
 
18
<body>
 
19
<div class="document" id="libtorrent-manual">
 
20
    <div id="container">
 
21
    <div id="headerNav">
 
22
    <ul>
 
23
    <li class="first"><a href="/">Home</a></li>
 
24
    <li><a href="../../products.html">Products</a></li>
 
25
    <li><a href="../../contact.html">Contact</a></li>
 
26
    </ul>
 
27
    </div>
 
28
    <div id="header">
 
29
    <h1><span>Rasterbar Software</span></h1>
 
30
    <h2><span>Software developement and consulting</span></h2>
 
31
    </div>
 
32
    <div id="main">
 
33
<h1 class="title">libtorrent manual</h1>
 
34
<table class="docinfo" frame="void" rules="none">
 
35
<col class="docinfo-name" />
 
36
<col class="docinfo-content" />
 
37
<tbody valign="top">
 
38
<tr><th class="docinfo-name">Author:</th>
 
39
<td>Arvid Norberg, <a class="last reference external" href="mailto:arvid&#64;rasterbar.com">arvid&#64;rasterbar.com</a></td></tr>
 
40
<tr><th class="docinfo-name">Version:</th>
 
41
<td>0.15.0</td></tr>
 
42
</tbody>
 
43
</table>
 
44
<div class="contents topic" id="table-of-contents">
 
45
<p class="topic-title first">Table of contents</p>
 
46
<ul class="simple">
 
47
<li><a class="reference internal" href="#tuning-libtorrent" id="id1">tuning libtorrent</a></li>
 
48
<li><a class="reference internal" href="#reducing-memory-footprint" id="id2">reducing memory footprint</a><ul>
 
49
<li><a class="reference internal" href="#disable-disk-cache" id="id3">disable disk cache</a></li>
 
50
<li><a class="reference internal" href="#remove-torrents" id="id4">remove torrents</a></li>
 
51
<li><a class="reference internal" href="#socket-buffer-sizes" id="id5">socket buffer sizes</a></li>
 
52
<li><a class="reference internal" href="#peer-list-size" id="id6">peer list size</a></li>
 
53
<li><a class="reference internal" href="#send-buffer-watermark" id="id7">send buffer watermark</a></li>
 
54
<li><a class="reference internal" href="#optimize-hashing-for-memory-usage" id="id8">optimize hashing for memory usage</a></li>
 
55
<li><a class="reference internal" href="#reduce-executable-size" id="id9">reduce executable size</a></li>
 
56
</ul>
 
57
</li>
 
58
<li><a class="reference internal" href="#play-nice-with-the-disk" id="id10">play nice with the disk</a></li>
 
59
<li><a class="reference internal" href="#high-performance-seeding" id="id11">high performance seeding</a><ul>
 
60
<li><a class="reference internal" href="#file-pool" id="id12">file pool</a></li>
 
61
<li><a class="reference internal" href="#disk-cache" id="id13">disk cache</a></li>
 
62
<li><a class="reference internal" href="#send-buffer-low-watermark" id="id14">send buffer low watermark</a></li>
 
63
<li><a class="reference internal" href="#peers" id="id15">peers</a></li>
 
64
<li><a class="reference internal" href="#torrent-limits" id="id16">torrent limits</a></li>
 
65
</ul>
 
66
</li>
 
67
<li><a class="reference internal" href="#benchmarking" id="id17">benchmarking</a><ul>
 
68
<li><a class="reference internal" href="#disk-metrics" id="id18">disk metrics</a></li>
 
69
<li><a class="reference internal" href="#session-stats" id="id19">session stats</a></li>
 
70
</ul>
 
71
</li>
 
72
<li><a class="reference internal" href="#contributions" id="id20">contributions</a></li>
 
73
</ul>
 
74
</div>
 
75
<div class="section" id="tuning-libtorrent">
 
76
<h1>tuning libtorrent</h1>
 
77
<p>libtorrent expose most constants used in the bittorrent engine for
 
78
customization through the <tt class="docutils literal"><span class="pre">session_settings</span></tt>. This makes it possible to
 
79
test and tweak the parameters for certain algorithms to make a client
 
80
that fits a wide range of needs. From low memory embedded devices to
 
81
servers seeding thousands of torrents. The default settings in libtorrent
 
82
are tuned for an end-user bittorrent client running on a normal desktop
 
83
computer.</p>
 
84
<p>This document describes techniques to benchmark libtorrent performance
 
85
and how parameters are likely to affect it.</p>
 
86
</div>
 
87
<div class="section" id="reducing-memory-footprint">
 
88
<h1>reducing memory footprint</h1>
 
89
<p>These are things you can do to reduce the memory footprint of libtorrent. You get
 
90
some of this by basing your default <tt class="docutils literal"><span class="pre">session_settings</span></tt> on the <tt class="docutils literal"><span class="pre">min_memory_usage()</span></tt>
 
91
setting preset function.</p>
 
92
<p>Keep in mind that lowering memory usage will affect performance, always profile
 
93
and benchmark your settings to determine if it's worth the trade-off.</p>
 
94
<p>The typical buffer usage of libtorrent, for a single download, with the cache
 
95
size set to 256 blocks (256 * 16 kiB = 4 MiB) is:</p>
 
96
<pre class="literal-block">
 
97
read cache:      128.6 (2058 kiB)
 
98
write cache:     103.5 (1656 kiB)
 
99
receive buffers: 7.3   (117 kiB)
 
100
send buffers:    4.8   (77 kiB)
 
101
hash temp:       0.001 (19 Bytes)
 
102
</pre>
 
103
<p>The receive buffers is proportional to the number of connections we make, and is
 
104
limited by the total number of connections in the session (default is 200).</p>
 
105
<p>The send buffers is proportional to the number of upload slots that are allowed
 
106
in the session. The default is auto configured based on the observed upload rate.</p>
 
107
<p>The read and write cache can be controlled (see section below).</p>
 
108
<p>The &quot;hash temp&quot; entry size depends on whether or not hashing is optimized for
 
109
speed or memory usage. In this test run it was optimized for memory usage.</p>
 
110
<div class="section" id="disable-disk-cache">
 
111
<h2>disable disk cache</h2>
 
112
<p>The bulk of the memory libtorrent will use is used for the disk cache. To save
 
113
the absolute most amount of memory, you can disable the cache by setting
 
114
<tt class="docutils literal"><span class="pre">session_settings::cache_size</span></tt> to 0. You might want to consider using the cache
 
115
but just disable caching read operations. You do this by settings
 
116
<tt class="docutils literal"><span class="pre">session_settings::use_read_cache</span></tt> to false. This is the main factor in how much
 
117
memory will be used by the client. Keep in mind that you will degrade performance
 
118
by disabling the cache. You should benchmark the disk access in order to make an
 
119
informed trade-off.</p>
 
120
</div>
 
121
<div class="section" id="remove-torrents">
 
122
<h2>remove torrents</h2>
 
123
<p>Torrents that have been added to libtorrent will inevitably use up memory, even
 
124
when it's paused. A paused torrent will not use any peer connection objects or
 
125
any send or receive buffers though. Any added torrent holds the entire .torrent
 
126
file in memory, it also remembers the entire list of peers that it's heard about
 
127
(which can be fairly long unless it's capped). It also retains information about
 
128
which blocks and pieces we have on disk, which can be significant for torrents
 
129
with many pieces.</p>
 
130
<p>If you need to minimize the memory footprint, consider removing torrents from
 
131
the session rather than pausing them. This will likely only make a difference
 
132
when you have a very large number of torrents in a session.</p>
 
133
<p>The downside of removing them is that they will no longer be auto-managed. Paused
 
134
auto managed torrents are scraped periodically, to determine which torrents are
 
135
in the greatest need of seeding, and libtorrent will prioritize to seed those.</p>
 
136
</div>
 
137
<div class="section" id="socket-buffer-sizes">
 
138
<h2>socket buffer sizes</h2>
 
139
<p>You can make libtorrent explicitly set the kernel buffer sizes of all its peer
 
140
sockets. If you set this to a low number, you may see reduced throughput, especially
 
141
for high latency connections. It is however an opportunity to save memory per
 
142
connection, and might be worth considering if you have a very large number of
 
143
peer connections. This memory will not be visible in your process, this sets
 
144
the amount of kernel memory is used for your sockets.</p>
 
145
<p>Change this by setting <tt class="docutils literal"><span class="pre">session_settings::recv_socket_buffer_size</span></tt> and
 
146
<tt class="docutils literal"><span class="pre">session_settings::send_socket_buffer_size</span></tt>.</p>
 
147
</div>
 
148
<div class="section" id="peer-list-size">
 
149
<h2>peer list size</h2>
 
150
<p>The default maximum for the peer list is 4000 peers. For IPv4 peers, each peer
 
151
entry uses 32 bytes, which ends up using 128 kB per torrent. If seeding 4 popular
 
152
torrents, the peer lists alone uses about half a megabyte.</p>
 
153
<p>The default limit is the same for paused torrents as well, so if you have a
 
154
large number of paused torrents (that are popular) it will be even more
 
155
significant.</p>
 
156
<p>If you're short of memory, you should consider lowering the limit. 500 is probably
 
157
enough. You can do this by setting <tt class="docutils literal"><span class="pre">session_settings::max_peerlist_size</span></tt> to
 
158
the max number of peers you want in the torrent's peer list.</p>
 
159
<p>You should also lower the same limit but for paused torrents. It might even make sense
 
160
to set that even lower, since you only need a few peers to start up while waiting
 
161
for the tracker and DHT to give you fresh ones. The max peer list size for paused
 
162
torrents is set by <tt class="docutils literal"><span class="pre">session_settings::max_paused_peerlist_size</span></tt>.</p>
 
163
<p>The drawback of lowering this number is that if you end up in a position where
 
164
the tracker is down for an extended period of time, your only hope of finding live
 
165
peers is to go through your list of all peers you've ever seen. Having a large
 
166
peer list will also help increase performance when starting up, since the torrent
 
167
can start connecting to peers in parallel with connecting to the tracker.</p>
 
168
</div>
 
169
<div class="section" id="send-buffer-watermark">
 
170
<h2>send buffer watermark</h2>
 
171
<p>The send buffer watermark controls when libtorrent will ask the disk I/O thread
 
172
to read blocks from disk, and append it to a peer's send buffer.</p>
 
173
<p>When the send buffer has fewer than or equal number of bytes as
 
174
<tt class="docutils literal"><span class="pre">session_settings::send_buffer_watermark</span></tt>, the peer will ask the disk I/O thread
 
175
for more data to send. The trade-off here is between wasting memory by having too
 
176
much data in the send buffer, and hurting send rate by starving out the socket,
 
177
waiting for the disk read operation to complete.</p>
 
178
<p>If your main objective is memory usage and you're not concerned about being able
 
179
to achieve high send rates, you can set the watermark to 9 bytes. This will guarantee
 
180
that no more than a single (16 kiB) block will be on the send buffer at a time, for
 
181
all peers. This is the least amount of memory possible for the send buffer.</p>
 
182
<p>You should benchmark your max send rate when adjusting this setting. If you have
 
183
a very fast disk, you are less likely see a performance hit.</p>
 
184
</div>
 
185
<div class="section" id="optimize-hashing-for-memory-usage">
 
186
<h2>optimize hashing for memory usage</h2>
 
187
<p>When libtorrent is doing hash checks of a file, or when it re-reads a piece that
 
188
was just completed to verify its hash, there are two options. The default one
 
189
is optimized for speed, which allocates buffers for the entire piece, reads in
 
190
the whole piece in one read call, then hashes it.</p>
 
191
<p>The second option is to optimize for memory usage instead, where a single buffer
 
192
is allocated, and the piece is read one block at a time, hashing it as each
 
193
block is read from the file. For low memory environments, this latter approach
 
194
is recommended. Change this by settings <tt class="docutils literal"><span class="pre">session_settings::optimize_hashing_for_speed</span></tt>
 
195
to false. This will significantly reduce peak memory usage, especially for
 
196
torrents with very large pieces.</p>
 
197
</div>
 
198
<div class="section" id="reduce-executable-size">
 
199
<h2>reduce executable size</h2>
 
200
<p>Compilers generally add a significant number of bytes to executables that make use
 
201
of C++ exceptions. By disabling exceptions (-fno-exceptions on GCC), you can
 
202
reduce the executable size with up to 45%. In order to build without exception
 
203
support, you need to patch parts of boost.</p>
 
204
<p>Also make sure to optimize for size when compiling.</p>
 
205
</div>
 
206
</div>
 
207
<div class="section" id="play-nice-with-the-disk">
 
208
<h1>play nice with the disk</h1>
 
209
<p>When checking a torrent, libtorrent will try to read as fast as possible from the disk.
 
210
The only thing that might hold it back is a CPU that is slow at calculating SHA-1 hashes,
 
211
but typically the file checking is limited by disk read speed. Most operating systems
 
212
today do not prioritize disk access based on the importance of the operation, this means
 
213
that checking a torrent might delay other disk accesses, such as virtual memory swapping
 
214
or just loading file by other (interactive) applications.</p>
 
215
<p>In order to play nicer with the disk, and leave some spare time for it to service other
 
216
processes that might be of higher importance to the end-user, you can introduce a sleep
 
217
between the disc accesses. This is a direct tradeoff between how fast you can check a
 
218
torrent and how soft you will hit the disk.</p>
 
219
<p>You control this by setting the <tt class="docutils literal"><span class="pre">session_settings::file_checks_delay_per_block</span></tt> to greater
 
220
than zero. This number is the number of milliseconds to sleep between each read of 16 kiB.</p>
 
221
<p>The sleeps are not necessarily in between each 16 kiB block (it might be read in larger chunks),
 
222
but the number will be multiplied by the number of blocks that were read, to maintain the
 
223
same semantics.</p>
 
224
</div>
 
225
<div class="section" id="high-performance-seeding">
 
226
<h1>high performance seeding</h1>
 
227
<p>In the case of a high volume seed, there are two main concerns. Performance and scalability.
 
228
This translates into high send rates, and low memory and CPU usage per peer connection.</p>
 
229
<div class="section" id="file-pool">
 
230
<h2>file pool</h2>
 
231
<p>libtorrent keeps an LRU file cache. Each file that is opened, is stuck in the cache. The main
 
232
purpose of this is because of anti-virus software that hooks on file-open and file close to
 
233
scan the file. Anti-virus software that does that will significantly increase the cost of
 
234
opening and closing files. However, for a high performance seed, the file open/close might
 
235
be so frequent that it becomes a significant cost. It might therefore be a good idea to allow
 
236
a large file descriptor cache. Adjust this though <tt class="docutils literal"><span class="pre">session_settings::file_pool_size</span></tt>.</p>
 
237
<p>Don't forget to set a high rlimit for file descriptors in your process as well. This limit
 
238
must be high enough to keep all connections and files open.</p>
 
239
</div>
 
240
<div class="section" id="disk-cache">
 
241
<h2>disk cache</h2>
 
242
<p>You typically want to set the cache size to as high as possible. The
 
243
<tt class="docutils literal"><span class="pre">session_settings::cache_size</span></tt> is specified in 16 kiB blocks. Since you're seeding,
 
244
the cache would be useless unless you also set <tt class="docutils literal"><span class="pre">session_settings::use_read_cache</span></tt>
 
245
to true.</p>
 
246
<p>In order to increase the possibility of read cache hits, set the
 
247
<tt class="docutils literal"><span class="pre">session_settings::cache_expiry</span></tt> to a large number. This won't degrade anything as
 
248
long as the client is only seeding, and not downloading any torrents.</p>
 
249
</div>
 
250
<div class="section" id="send-buffer-low-watermark">
 
251
<h2>send buffer low watermark</h2>
 
252
<p>libtorrent uses a low watermark for send buffers to determine when a new piece should
 
253
be requested from the disk I/O subsystem, to be appended to the send buffer. The low
 
254
watermark is determined based on the send rate of the socket. It needs to be large
 
255
enough to not draining the socket's send buffer before the disk operation completes.</p>
 
256
<p>The watermark is bound to a max value, to avoid buffer sizes growing out of control.
 
257
The default max send buffer size might not be enough to sustain very high upload rates,
 
258
and you might have to increase it. It's specified in bytes in
 
259
<tt class="docutils literal"><span class="pre">session_settings::send_buffer_watermark</span></tt>. The <tt class="docutils literal"><span class="pre">high_performance_seed()</span></tt> preset
 
260
sets this value to 5 MB.</p>
 
261
</div>
 
262
<div class="section" id="peers">
 
263
<h2>peers</h2>
 
264
<p>First of all, in order to allow many connections, set the global connection limit
 
265
high, <tt class="docutils literal"><span class="pre">session::set_max_connections()</span></tt>. Also set the upload rate limit to
 
266
infinite, <tt class="docutils literal"><span class="pre">session::set_upload_rate_limit()</span></tt>, passing 0 means infinite.</p>
 
267
<p>When dealing with a large number of peers, it might be a good idea to have slightly
 
268
stricter timeouts, to get rid of lingering connections as soon as possible.</p>
 
269
<p>There are a couple of relevant settings: <tt class="docutils literal"><span class="pre">session_settings::request_timeout</span></tt>,
 
270
<tt class="docutils literal"><span class="pre">session_settings::peer_timeout</span></tt> and <tt class="docutils literal"><span class="pre">session_settings::inactivity_timeout</span></tt>.</p>
 
271
<p>For seeds that are critical for a delivery system, you most likely want to allow
 
272
multiple connections from the same IP. That way two people from behind the same NAT
 
273
can use the service simultaneously. This is controlled by
 
274
<tt class="docutils literal"><span class="pre">session_settings::allow_multiple_connections_per_ip</span></tt>.</p>
 
275
<p>In order to always unchoke peers, turn off automatic unchoke
 
276
<tt class="docutils literal"><span class="pre">session_settings::auto_upload_slots</span></tt> and set the number of upload slots to a large
 
277
number via <tt class="docutils literal"><span class="pre">session::set_max_uploads()</span></tt>, or use -1 (which means infinite).</p>
 
278
</div>
 
279
<div class="section" id="torrent-limits">
 
280
<h2>torrent limits</h2>
 
281
<p>To seed thousands of torrents, you need to increase the <tt class="docutils literal"><span class="pre">session_settings::active_limit</span></tt>
 
282
and <tt class="docutils literal"><span class="pre">session_settings::active_seeds</span></tt>.</p>
 
283
</div>
 
284
</div>
 
285
<div class="section" id="benchmarking">
 
286
<h1>benchmarking</h1>
 
287
<p>There are a bunch of built-in instrumentation of libtorrent that can be used to get an insight
 
288
into what it's doing and how well it performs. This instrumentation is enabled by defining
 
289
preprocessor symbols when building.</p>
 
290
<p>There are also a number of scripts that parses the log files and generates graphs (requires
 
291
gnuplot and python).</p>
 
292
<div class="section" id="disk-metrics">
 
293
<h2>disk metrics</h2>
 
294
<p>To enable disk I/O instrumentation, define <tt class="docutils literal"><span class="pre">TORRENT_DISK_STATS</span></tt> when building. When built
 
295
with this configuration libtorrent will create three log files, measuring various aspects of
 
296
the disk I/O. The following table is an overview of these files and what they measure.</p>
 
297
<table border="1" class="docutils">
 
298
<colgroup>
 
299
<col width="30%" />
 
300
<col width="70%" />
 
301
</colgroup>
 
302
<thead valign="bottom">
 
303
<tr><th class="head">filename</th>
 
304
<th class="head">description</th>
 
305
</tr>
 
306
</thead>
 
307
<tbody valign="top">
 
308
<tr><td><tt class="docutils literal"><span class="pre">disk_io_thread.log</span></tt></td>
 
309
<td>This is a log of which operation the disk I/O thread is
 
310
engaged in, with timestamps. This tells you what the thread
 
311
is spending its time doing.</td>
 
312
</tr>
 
313
<tr><td><tt class="docutils literal"><span class="pre">disk_buffers.log</span></tt></td>
 
314
<td>This log keeps track of what the buffers allocated from the
 
315
disk buffer pool are used for. There are 5 categories.
 
316
receive buffer, send buffer, write cache, read cache and
 
317
temporary hash storage. This is key when optimizing memory
 
318
usage.</td>
 
319
</tr>
 
320
<tr><td><tt class="docutils literal"><span class="pre">disk_access.log</span></tt></td>
 
321
<td>This is a low level log of read and write operations, with
 
322
timestamps and file offsets. The file offsets are byte
 
323
offsets in the torrent (not in any particular file, in the
 
324
case of a multi-file torrent). This can be used as an
 
325
estimate of the physical drive location. The purpose of
 
326
this log is to identify the amount of seeking the drive has
 
327
to do.</td>
 
328
</tr>
 
329
</tbody>
 
330
</table>
 
331
<div class="section" id="disk-io-thread-log">
 
332
<h3>disk_io_thread.log</h3>
 
333
<p>The structure of this log is simple. For each line, there are two columns, a timestamp and
 
334
the operation that was started. There is a special operation called <tt class="docutils literal"><span class="pre">idle</span></tt> which means
 
335
it looped back to the top and started waiting for new jobs. If there are more jobs to
 
336
handle immediately, the <tt class="docutils literal"><span class="pre">idle</span></tt> state is still there, but the timestamp is the same as the
 
337
next job that is handled.</p>
 
338
<p>Some operations have a 3:rd column with an optional parameter. <tt class="docutils literal"><span class="pre">read</span></tt> and <tt class="docutils literal"><span class="pre">write</span></tt> tells
 
339
you the number of bytes that were requested to be read or written. <tt class="docutils literal"><span class="pre">flushing</span></tt> tells you
 
340
the number of bytes that were flushed from the disk cache.</p>
 
341
<p>This is an example excerpt from a log:</p>
 
342
<pre class="literal-block">
 
343
3702 idle
 
344
3706 check_fastresume
 
345
3707 idle
 
346
4708 save_resume_data
 
347
4708 idle
 
348
8230 read 16384
 
349
8255 idle
 
350
8431 read 16384
 
351
</pre>
 
352
<p>The script to parse this log and generate a graph is called <tt class="docutils literal"><span class="pre">parse_disk_log.py</span></tt>. It takes
 
353
the log file as the first command line argument, and produces a file: <tt class="docutils literal"><span class="pre">disk_io.png</span></tt>.
 
354
The time stamp is in milliseconds since start.</p>
 
355
<p>You can pass in a second, optional, argument to specify the window size it will average
 
356
the time measurements over. The default is 5 seconds. For long test runs, it might be interesting
 
357
to increase that number. It is specified as a number of seconds.</p>
 
358
<img alt="disk_io.png" src="disk_io.png" />
 
359
<p>This is an example graph generated by the parse script.</p>
 
360
</div>
 
361
<div class="section" id="disk-buffers-log">
 
362
<h3>disk_buffers.log</h3>
 
363
<p>The disk buffer log tells you where the buffer memory is used. The log format has a time stamp,
 
364
the name of the buffer usage which use-count changed, colon, and the new number of blocks that are
 
365
in use for this particular key. For example:</p>
 
366
<pre class="literal-block">
 
367
23671 write cache: 18
 
368
23671 receive buffer: 3
 
369
24153 receive buffer: 2
 
370
24153 write cache: 19
 
371
24154 receive buffer: 3
 
372
24198 receive buffer: 2
 
373
24198 write cache: 20
 
374
24202 receive buffer: 3
 
375
24305 send buffer: 0
 
376
24305 send buffer: 1
 
377
24909 receive buffer: 2
 
378
24909 write cache: 21
 
379
24910 receive buffer: 3
 
380
</pre>
 
381
<p>The time stamp is in milliseconds since start.</p>
 
382
<p>To generate a graph, use <tt class="docutils literal"><span class="pre">parse_disk_buffer_log.py</span></tt>. It takes the log file as the first
 
383
command line argument. It generates <tt class="docutils literal"><span class="pre">disk_buffer.png</span></tt>.</p>
 
384
<img alt="disk_buffer_sample.png" src="disk_buffer_sample.png" />
 
385
<p>This is an example graph generated by the parse script.</p>
 
386
</div>
 
387
<div class="section" id="disk-access-log">
 
388
<h3>disk_access.log</h3>
 
389
<p>The disc access log has three fields. The timestamp (milliseconds since start), operation
 
390
and offset. The offset is the absolute offset within the torrent (not within a file). This
 
391
log is only useful when you're downloading a single torrent, otherwise the offsets will not
 
392
be unique.</p>
 
393
<p>In order to easily plot this directly in gnuplot, without parsing it, there are two lines
 
394
associated with each read or write operation. The first one is the offset where the operation
 
395
started, and the second one is where the operation ended.</p>
 
396
<p>Example:</p>
 
397
<pre class="literal-block">
 
398
15437 read 301187072
 
399
15437 read_end 301203456
 
400
16651 read 213385216
 
401
16680 read_end 213647360
 
402
25879 write 249036800
 
403
25879 write_end 249298944
 
404
26811 read 325582848
 
405
26943 read_end 325844992
 
406
36736 read 367001600
 
407
36766 read_end 367263744
 
408
</pre>
 
409
<p>The disk access log does not have any good visualization tool yet. There is however a gnuplot
 
410
file, <tt class="docutils literal"><span class="pre">disk_access.gnuplot</span></tt> which assumes <tt class="docutils literal"><span class="pre">disk_access.log</span></tt> is in the current directory.</p>
 
411
<img alt="disk_access.png" src="disk_access.png" />
 
412
<p>The density of the disk seeks tells you how hard the drive has to work.</p>
 
413
</div>
 
414
</div>
 
415
<div class="section" id="session-stats">
 
416
<h2>session stats</h2>
 
417
<p>By defining <tt class="docutils literal"><span class="pre">TORRENT_STATS</span></tt> libtorrent will write a log file called <tt class="docutils literal"><span class="pre">session_stats.log</span></tt> which
 
418
is in a format ready to be passed directly into gnuplot. The parser script <tt class="docutils literal"><span class="pre">parse_session_stats.py</span></tt>
 
419
will however parse out the field names and generate 3 different views of the data. This script
 
420
is easy to modify to generate the particular view you're interested in.</p>
 
421
<p>The first line in the log contains all the field names, separated by colon:</p>
 
422
<pre class="literal-block">
 
423
second:upload rate:download rate:downloading torrents:seeding torrents:peers...
 
424
</pre>
 
425
<p>The rest of the log is one line per second with all the fields' values.</p>
 
426
<p>These are the fields:</p>
 
427
<table border="1" class="docutils">
 
428
<colgroup>
 
429
<col width="25%" />
 
430
<col width="75%" />
 
431
</colgroup>
 
432
<thead valign="bottom">
 
433
<tr><th class="head">field name</th>
 
434
<th class="head">description</th>
 
435
</tr>
 
436
</thead>
 
437
<tbody valign="top">
 
438
<tr><td>second</td>
 
439
<td>the time, in seconds, for this log line</td>
 
440
</tr>
 
441
<tr><td>upload rate</td>
 
442
<td>the number of bytes uploaded in the last second</td>
 
443
</tr>
 
444
<tr><td>download rate</td>
 
445
<td>the number of bytes downloaded in the last second</td>
 
446
</tr>
 
447
<tr><td>downloading torrents</td>
 
448
<td>the number of torrents that are not seeds</td>
 
449
</tr>
 
450
<tr><td>seeding torrents</td>
 
451
<td>the number of torrents that are seed</td>
 
452
</tr>
 
453
<tr><td>peers</td>
 
454
<td>the total number of connected peers</td>
 
455
</tr>
 
456
<tr><td>connecting peers</td>
 
457
<td>the total number of peers attempting to connect (half-open)</td>
 
458
</tr>
 
459
<tr><td>disk block buffers</td>
 
460
<td>the total number of disk buffer blocks that are in use</td>
 
461
</tr>
 
462
<tr><td>unchoked peers</td>
 
463
<td>the total number of unchoked peers</td>
 
464
</tr>
 
465
<tr><td>num list peers</td>
 
466
<td>the total number of known peers, but not necessarily connected</td>
 
467
</tr>
 
468
<tr><td>peer allocations</td>
 
469
<td>the total number of allocations for the peer list pool</td>
 
470
</tr>
 
471
<tr><td>peer storage bytes</td>
 
472
<td>the total number of bytes allocated for the peer list pool</td>
 
473
</tr>
 
474
</tbody>
 
475
</table>
 
476
<p>This is an example of a graph that can be generated from this log:</p>
 
477
<img alt="session_stats_peers.png" src="session_stats_peers.png" />
 
478
<p>It shows statistics about the number of peers and peers states. How at the startup
 
479
there are a lot of half-open connections, which tapers off as the total number of
 
480
peers approaches the limit (50). It also shows how the total peer list slowly but steadily
 
481
grows over time. This list is plotted against the right axis, as it has a different scale
 
482
as the other fields.</p>
 
483
</div>
 
484
</div>
 
485
<div class="section" id="contributions">
 
486
<h1>contributions</h1>
 
487
<p>If you have added instrumentation for some part of libtorrent that is not covered here, or
 
488
if you have improved any of the parser scrips, please consider contributing it back to the
 
489
project.</p>
 
490
<p>If you have run tests and found that some algorithm or default value in libtorrent is
 
491
suboptimal, please contribute that knowledge back as well, to allow us to improve the library.</p>
 
492
<p>If you have additional suggestions on how to tune libtorrent for any specific use case,
 
493
please let us know and we'll update this document.</p>
 
494
</div>
 
495
    </div>
 
496
    <div id="footer">
 
497
    <span>Copyright &copy; 2005 Rasterbar Software.</span>
 
498
    </div>
 
499
    </div>
 
500
    <script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
 
501
    </script>
 
502
    <script type="text/javascript">
 
503
    _uacct = "UA-1599045-1";
 
504
    urchinTracker();
 
505
    </script>
 
506
</div>
 
507
</body>
 
508
</html>