|
1 | | -## CPU load testing kit in Rust |
2 | | -`test_cpu_parallel` is basic CPU workload generator written in Rust. |
3 | | -It runs a CPU-burning loop using multithreading, with configurable parallelism degree. |
| 1 | +# test_cpu_parallel – CPU & Memory Load Generator in Rust |
4 | 2 |
|
5 | | -More Detailed instructions available at [Project homepage:](../README.md) |
| 3 | +[](https://crates.io/crates/test_cpu_parallel) |
| 4 | +[](https://docs.rs/test_cpu_parallel) |
6 | 5 |
|
7 | | ----- |
8 | | -Compile the tool using Rust with: `cargo build` |
9 | | - - Using `cargo build --release` is not recommended for this tool, |
10 | | - as the optimizations play against the simple "CPU burning loop" implemented in the tool |
11 | | - - The Cargo version used for compiling has an impact on the output, notably the performance of the tool. |
12 | | - - Version 1.3.0, compiled with Cargo version 1.86.0 |
| 6 | +`test_cpu_parallel` is a **small, zero‑dependency load‑testing kit**. It can: |
13 | 7 |
|
14 | | -Note: To compile a Rust project, you need to have the Rust programming language and its associated |
15 | | - tools installed on your system. If you haven't installed Rust yet, you can do so by following |
16 | | - the instructions at https://www.rust-lang.org/tools/install |
| 8 | +* load cores to verify scaling or system/container limits |
| 9 | +* sweep 1 → *N* threads and export a tidy CSV for speed‑up plots |
| 10 | +* hammer the memory hierarchy with random‑access touches beyond the LLC |
| 11 | +* run **stand‑alone** from the CLI *or* be **embedded** in your own Rust code |
17 | 12 |
|
18 | | -Examples: |
19 | | -``` |
20 | | -# Run data collection with parallelism 2 |
21 | | -./test_cpu_parallel -w 2 |
| 13 | +A two‑minute build, no external data files, works on Linux, macOS and Windows. |
| 14 | + |
| 15 | +Link to the [Project page](https://github.com/LucaCanali/Miscellaneous/tree/master/Performance_Testing/Test_CPU_parallel_Rust) |
| 16 | + |
| 17 | +--- |
| 18 | +## 📦 Installation |
22 | 19 |
|
23 | | -# Get the help message |
24 | | -./test_cpu_parallel --help |
| 20 | +| what you want | command | |
| 21 | +|------------------------------|---------| |
| 22 | +| **CLI binary** (optimised) | `cargo install test_cpu_parallel` | |
| 23 | +| **Library** in an app / lib | `cargo add test_cpu_parallel` | |
| 24 | +| **Dev build from source** | `git clone … && cargo build` | |
25 | 25 |
|
26 | | -Use test_cpu_parallel to generate CPU-intensive load on a system |
27 | | -The tool runs multi-threaded loops with configurable parallelism |
28 | | -Two workload types are implemented: CPU-intensive (default) and memory-intensive |
29 | | -The output reports measurements of the workload execution time as a function of load |
30 | | -Project homepage: https://github.com/LucaCanali/Miscellaneous/tree/master/Performance_Testing/Test_CPU_parallel_Rust |
| 26 | +> **Note** For benchmark *accuracy* the CLI defaults to an **un‑optimised** `opt‑level = 0` build. If you install with `cargo install` a `--release` build is produced; results will differ slightly. Re‑compile locally with `cargo build` to reproduce blog numbers. |
31 | 27 |
|
32 | | -Example: |
33 | | -./test_CPU_parallel --num_workers 2 |
| 28 | +--- |
| 29 | +## ⚡ CLI quick‑start |
34 | 30 |
|
| 31 | +```bash |
| 32 | +# Burn four threads for a few seconds |
| 33 | +$ test_cpu_parallel -w 4 |
| 34 | + |
| 35 | +# Sweep 1 → 16 threads, write CSV |
| 36 | +$ test_cpu_parallel --num_workers 16 --full -o results.csv |
| 37 | + |
| 38 | +# Stress memory with 8 workers and a 512 MiB buffer |
| 39 | +$ test_cpu_parallel -w 8 --mode memory --memory_size 512 |
| 40 | +``` |
35 | 41 |
|
| 42 | +Run `test_cpu_parallel --help` for the complete flag list (excerpt below). |
| 43 | + |
| 44 | +```text |
36 | 45 | Usage: test_cpu_parallel [OPTIONS] |
| 46 | + -w, --num_workers <N> parallel threads (default 2) |
| 47 | + -m, --mode <cpu|memory> workload type (default cpu) |
| 48 | + -f, --full sweep 1‥=N threads |
| 49 | + -o, --output_file <PATH> write CSV (full mode) |
| 50 | + --memory_size <MiB> buffer for memory test (default 1024) |
| 51 | +``` |
| 52 | + |
| 53 | +--- |
| 54 | +## 📚 Library usage |
| 55 | + |
| 56 | +Embed the engine in unit tests, benchmarks or monitoring agents: |
| 57 | + |
| 58 | +```rust |
| 59 | +use test_cpu_parallel::TestCPUParallel; |
37 | 60 |
|
38 | | -Options: |
39 | | - -f, --full |
40 | | - Full mode will test all the values of num_workers from 1 to the value set with --num_workers, use this to collect speedup test measurements and create plots, default = False |
41 | | - -w, --num_workers <num_workers> |
42 | | - Number of parallel threads running concurrently [default: 2] |
43 | | - -o, --output_file <output_file> |
44 | | - Optional output file, applies only to the full mode [default: ] |
45 | | - -m, --mode <mode> |
46 | | - Specifies the workload mode: 'cpu' for CPU-intensive or 'memory' for memory-intensive [default: cpu] [possible values: cpu, memory] |
47 | | - --num_job_execution_loops <num_job_execution_loops> |
48 | | - Number of times the execution loop is run on each worker [default: 3] |
49 | | - --worker_inner_loop_size <worker_inner_loop_size> |
50 | | - Number of iterations in the inner loop of the worker thread [default: 1000] |
51 | | - --memory_size <memory_size> |
52 | | - Size of the buffer used by the 'memory' mode in MB, rounded to next power of 2 if needed. [default: 1024] |
53 | | - -h, --help |
54 | | - Print help |
55 | | - -V, --version |
56 | | - Print version |
| 61 | +fn main() -> anyhow::Result<()> { |
| 62 | + // 4 workers, one batch, memory workload, 64 MiB buffer |
| 63 | + let bench = TestCPUParallel::new(4, 1, 1_000, "", 64); |
| 64 | + let (thread_stats, batch_stats) = bench.test_one_load(None, "memory")?; |
| 65 | + println!("Per‑thread stats: {thread_stats:?}"); |
| 66 | + println!("Per‑batch stats: {batch_stats:?}"); |
| 67 | + Ok(()) |
| 68 | +} |
57 | 69 | ``` |
| 70 | + |
| 71 | +API docs are hosted on **[docs.rs/test_cpu_parallel](https://docs.rs/test_cpu_parallel)**. |
| 72 | + |
| 73 | +--- |
| 74 | +## 🔧 Building from source |
| 75 | + |
| 76 | +```bash |
| 77 | +# Clone and build a debug binary (recommended for comparable timings) |
| 78 | +$ git clone https://github.com/LucaCanali/Miscellaneous.git |
| 79 | +$ cd Miscellaneous/Performance_Testing/Test_CPU_parallel_Rust |
| 80 | +$ cargo build # ≈ 35 s on a modern laptop |
| 81 | +``` |
| 82 | + |
| 83 | +* Tested on Rust **1.74+** – that is the MSRV. |
| 84 | +* Setting `cargo build --release` enables heavy optimisations and changes loop timing; avoid if you care about exact comparability. |
| 85 | + |
| 86 | +--- |
| 87 | +## 📊 Analysing the CSV |
| 88 | + |
| 89 | +Full‑mode output is a single CSV line per thread count, ready to feed into |
| 90 | +Python/pandas, gnuplot or Excel. See the `Notebooks/` directory in the repo for ready‑made Jupyter notebooks that plot speed‑up and efficiency curves. |
| 91 | + |
| 92 | +--- |
| 93 | +## More |
| 94 | + |
| 95 | +* Project page & extended docs – <https://github.com/LucaCanali/Miscellaneous/tree/master/Performance_Testing/Test_CPU_parallel_Rust> |
| 96 | +* Blog article that motivated the tool – <https://db-blog.web.cern.ch/node/189> |
| 97 | +* Licence – **Apache‑2.0** |
| 98 | + |
| 99 | +Enjoy hacking your CPUs 🔥 |
| 100 | + |
0 commit comments