Skip to content
This repository was archived by the owner on Oct 3, 2024. It is now read-only.

Commit e51bd8a

Browse files
committed
feat: [#161] review article: Profiling the Torrust BitTorrent ...
1 parent b6d76fc commit e51bd8a

File tree

2 files changed

+62
-51
lines changed

2 files changed

+62
-51
lines changed

project-words.txt

+1
Original file line numberDiff line numberDiff line change
@@ -89,4 +89,5 @@ webp
8989
webroot
9090
Werror
9191
WORKDIR
92+
Xacrimon
9293
Xdebug

src/routes/(blog-article)/profiling-the-torrust-bittorrent-udp-tracker/+page.md

+61-51
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ In our quest to elevate the Torrust BitTorrent Tracker's performance, we've embr
5151

5252
In the previous article we introduced to the community the benchmarking tools we are using at the moment to know whether the Tracker performs at the same level as other applications on the market.
5353

54-
With those benchmarking tools we ensure that the Tracker has a good performance and we don't have regressions. If you are curious about how we do benchmarking you can read the "[Benchmarking the Torrust BitTorrent Tracker]about(benchmarking-the-torrust-bittorrent-tracker)" article.
54+
With those benchmarking tools we ensure that the Tracker has a good performance and we don't have regressions. If you are curious about how we do benchmarking you can read the "[Benchmarking the Torrust BitTorrent Tracker](benchmarking-the-torrust-bittorrent-tracker)" article.
5555

5656
In this article we will explain how we are collecting metrics to know which parts of the code we should improve.
5757

@@ -107,68 +107,78 @@ The `announce` request is the most important request a tracker needs to handle.
107107

108108
Every request is a write/read request. The system is intensive in writes. All requests eventually try to acquire a write lock to include themselves in the peer list. That's why we think that's the main bottleneck in our implementation, at the moment. For that reason we have been trying different implementations of the torrents repository:
109109

110-
- `tokio::sync::RwLock<std::collections::BTreeMap<InfoHash, Entry>>`
111-
- `std::sync::RwLock<std::collections::BTreeMap<InfoHash, Entry>>`
112-
- `std::sync::RwLock<std::collections::BTreeMap<InfoHash, Arc<std::sync::Mutex<Entry>>>>`
113-
- `tokio::sync::RwLock<std::collections::BTreeMap<InfoHash, Arc<std::sync::Mutex<Entry>>>>`
114-
- `tokio::sync::RwLock<std::collections::BTreeMap<InfoHash, Arc<tokio::sync::Mutex<Entry>>>>`
110+
<CodeBlock lang="rust">
111+
112+
```rust
113+
pub type TorrentsRwLockStd = RwLockStd<EntrySingle>;
114+
pub type TorrentsRwLockStdMutexStd = RwLockStd<EntryMutexStd>;
115+
pub type TorrentsRwLockStdMutexTokio = RwLockStd<EntryMutexTokio>;
116+
pub type TorrentsRwLockTokio = RwLockTokio<EntrySingle>;
117+
pub type TorrentsRwLockTokioMutexStd = RwLockTokio<EntryMutexStd>;
118+
pub type TorrentsRwLockTokioMutexTokio = RwLockTokio<EntryMutexTokio>;
119+
pub type TorrentsSkipMapMutexStd = CrossbeamSkipList<EntryMutexStd>; // Default
120+
pub type TorrentsSkipMapMutexParkingLot = CrossbeamSkipList<EntryMutexParkingLot>;
121+
pub type TorrentsSkipMapRwLockParkingLot = CrossbeamSkipList<EntryRwLockParkingLot>;
122+
pub type TorrentsDashMapMutexStd = XacrimonDashMap<EntryMutexStd>;
123+
```
124+
125+
</CodeBlock>
115126

116-
The first one it's the default one when you run the tracker. We are benchmarking all the implementations.
127+
The default implementation used in production is `TorrentsSkipMapMutexStd`.
117128

118129
<Callout type="info">
119130

120-
NOTICE: All implementations are based on the `BTreeMap`. The reason we use a `BTreeMap` is because the tracker API has an endpoint where you can get the ordered list of all torrents in the tracker repository.
131+
**NOTICE**: All implementations are based on types that support ordering like `BTreeMap` or `SkipMap`. The reason we use those types is because the tracker API has an endpoint where you can get the ordered list of all torrents in the tracker repository.
121132

122133
</Callout>
123134

124-
We are implementing a new repository using a different data structure that allows concurrent writes called [DashMap](https://docs.rs/dashmap/latest/dashmap/).
125-
126135
## Internal Repository Benchmarking
127136

128137
As we explained in a previous article ("[Benchmarking the Torrust BitTorrent Tracker](benchmarking-the-torrust-bittorrent-tracker)") you can run the benchmark for those different repository implementations with the following command:
129138

130139
<CodeBlock lang="terminal">
131140

132141
```terminal
133-
cargo run --release -p torrust-torrent-repository-benchmarks -- --threads 4 --sleep 0 --compare true
142+
cargo bench -p torrust-tracker-torrent-repository
134143
```
135144

136145
</CodeBlock>
137146

138-
The output at the time of writing this post is:
147+
The output at the time of writing this post is similar to:
139148

140149
<CodeBlock lang="terminal">
141150

142151
```terminal
143-
tokio::sync::RwLock<std::collections::BTreeMap<InfoHash, Entry>>
144-
add_one_torrent: Avg/AdjAvg: (60ns, 59ns)
145-
update_one_torrent_in_parallel: Avg/AdjAvg: (10.909457ms, 0ns)
146-
add_multiple_torrents_in_parallel: Avg/AdjAvg: (13.88879ms, 0ns)
147-
update_multiple_torrents_in_parallel: Avg/AdjAvg: (7.772484ms, 7.782535ms)
148-
149-
std::sync::RwLock<std::collections::BTreeMap<InfoHash, Entry>>
150-
add_one_torrent: Avg/AdjAvg: (43ns, 39ns)
151-
update_one_torrent_in_parallel: Avg/AdjAvg: (4.020937ms, 4.020937ms)
152-
add_multiple_torrents_in_parallel: Avg/AdjAvg: (5.896177ms, 5.768448ms)
153-
update_multiple_torrents_in_parallel: Avg/AdjAvg: (3.883823ms, 3.883823ms)
154-
155-
std::sync::RwLock<std::collections::BTreeMap<InfoHash, Arc<std::sync::Mutex<Entry>>>>
156-
add_one_torrent: Avg/AdjAvg: (51ns, 49ns)
157-
update_one_torrent_in_parallel: Avg/AdjAvg: (3.252314ms, 3.149109ms)
158-
add_multiple_torrents_in_parallel: Avg/AdjAvg: (8.411094ms, 8.411094ms)
159-
update_multiple_torrents_in_parallel: Avg/AdjAvg: (4.106086ms, 4.106086ms)
160-
161-
tokio::sync::RwLock<std::collections::BTreeMap<InfoHash, Arc<std::sync::Mutex<Entry>>>>
162-
add_one_torrent: Avg/AdjAvg: (91ns, 90ns)
163-
update_one_torrent_in_parallel: Avg/AdjAvg: (3.542378ms, 3.435695ms)
164-
add_multiple_torrents_in_parallel: Avg/AdjAvg: (15.651172ms, 15.651172ms)
165-
update_multiple_torrents_in_parallel: Avg/AdjAvg: (4.368189ms, 4.257572ms)
166-
167-
tokio::sync::RwLock<std::collections::BTreeMap<InfoHash, Arc<tokio::sync::Mutex<Entry>>>>
168-
add_one_torrent: Avg/AdjAvg: (111ns, 109ns)
169-
update_one_torrent_in_parallel: Avg/AdjAvg: (6.590677ms, 6.808535ms)
170-
add_multiple_torrents_in_parallel: Avg/AdjAvg: (16.572217ms, 16.30488ms)
171-
update_multiple_torrents_in_parallel: Avg/AdjAvg: (4.073221ms, 4.000122ms)
152+
Running benches/repository_benchmark.rs (target/release/deps/repository_benchmark-a9b0013c8d09c3c3)
153+
add_one_torrent/RwLockStd
154+
time: [63.057 ns 63.242 ns 63.506 ns]
155+
Found 12 outliers among 100 measurements (12.00%)
156+
2 (2.00%) low severe
157+
2 (2.00%) low mild
158+
2 (2.00%) high mild
159+
6 (6.00%) high severe
160+
add_one_torrent/RwLockStdMutexStd
161+
time: [62.505 ns 63.077 ns 63.817 ns]
162+
Found 11 outliers among 100 measurements (11.00%)
163+
4 (4.00%) high mild
164+
7 (7.00%) high severe
165+
Benchmarking add_one_torrent/RwLockStdMutexTokio: Collecting 100 samples in estimated 1.0004 s (10M iterationsadd_one_torrent/RwLockStdMutexTokio
166+
time: [98.440 ns 98.551 ns 98.660 ns]
167+
Found 4 outliers among 100 measurements (4.00%)
168+
3 (3.00%) low mild
169+
1 (1.00%) high severe
170+
add_one_torrent/RwLockTokio
171+
time: [107.84 ns 108.18 ns 108.54 ns]
172+
Found 3 outliers among 100 measurements (3.00%)
173+
2 (2.00%) low mild
174+
1 (1.00%) high mild
175+
Benchmarking add_one_torrent/RwLockTokioMutexStd: Collecting 100 samples in estimated 1.0001 s (8.7M iterationadd_one_torrent/RwLockTokioMutexStd
176+
time: [116.34 ns 116.48 ns 116.63 ns]
177+
Found 2 outliers among 100 measurements (2.00%)
178+
1 (1.00%) high mild
179+
1 (1.00%) high severe
180+
Benchmarking add_one_torrent/RwLockTokioMutexTokio: Collecting 100 samples in estimated 1.0005 s (6.9M iteratiadd_one_torrent/RwLockTokioMutexTokio
181+
time: [143.39 ns 143.51 ns 143.63 ns]
172182
```
173183

174184
</CodeBlock>
@@ -186,16 +196,16 @@ In order to profile the UDP tracker you need to:
186196

187197
Build and run the binary for profiling with:
188198

189-
<CodeBlock lang="terminal">
199+
<CodeBlock lang="console">
190200

191-
```terminal
192-
RUSTFLAGS='-g' cargo build --release --bin profiling \
193-
&& export TORRUST_TRACKER_PATH_CONFIG="./share/default/config/tracker.udp.benchmarking.toml" \
194-
&& valgrind \
195-
--tool=callgrind \
196-
--callgrind-out-file=callgrind.out \
197-
--collect-jumps=yes \
198-
--simulate-cache=yes \
201+
```console
202+
RUSTFLAGS='-g' cargo build --release --bin profiling \\
203+
&& export TORRUST_TRACKER_CONFIG_TOML_PATH="./share/default/config/tracker.udp.benchmarking.toml" \\
204+
&& valgrind \\
205+
--tool=callgrind \\
206+
--callgrind-out-file=callgrind.out \\
207+
--collect-jumps=yes \\
208+
--simulate-cache=yes \\
199209
./target/release/profiling 60
200210
```
201211

@@ -248,7 +258,7 @@ After installing the `cargo flamegraph` package you can generate the flamegraph
248258
<CodeBlock lang="terminal">
249259

250260
```terminal
251-
TORRUST_TRACKER_PATH_CONFIG="./share/default/config/tracker.udp.benchmarking.toml" cargo flamegraph --bin=profiling -- 60
261+
TORRUST_TRACKER_CONFIG_TOML_PATH="./share/default/config/tracker.udp.benchmarking.toml" cargo flamegraph --bin=profiling -- 60
252262
```
253263

254264
</CodeBlock>

0 commit comments

Comments
 (0)