base lib with cpu benchmark and basic cli
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
/target
|
||||||
400
Cargo.lock
generated
Normal file
400
Cargo.lock
generated
Normal file
@@ -0,0 +1,400 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 4
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstream"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d"
|
||||||
|
dependencies = [
|
||||||
|
"anstyle",
|
||||||
|
"anstyle-parse",
|
||||||
|
"anstyle-query",
|
||||||
|
"anstyle-wincon",
|
||||||
|
"colorchoice",
|
||||||
|
"is_terminal_polyfill",
|
||||||
|
"utf8parse",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle"
|
||||||
|
version = "1.0.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle-parse"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e"
|
||||||
|
dependencies = [
|
||||||
|
"utf8parse",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle-query"
|
||||||
|
version = "1.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc"
|
||||||
|
dependencies = [
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle-wincon"
|
||||||
|
version = "3.0.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d"
|
||||||
|
dependencies = [
|
||||||
|
"anstyle",
|
||||||
|
"once_cell_polyfill",
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "2.11.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap"
|
||||||
|
version = "4.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b193af5b67834b676abd72466a96c1024e6a6ad978a1f484bd90b85c94041351"
|
||||||
|
dependencies = [
|
||||||
|
"clap_builder",
|
||||||
|
"clap_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap_builder"
|
||||||
|
version = "4.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f"
|
||||||
|
dependencies = [
|
||||||
|
"anstream",
|
||||||
|
"anstyle",
|
||||||
|
"clap_lex",
|
||||||
|
"strsim",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap_derive"
|
||||||
|
version = "4.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1110bd8a634a1ab8cb04345d8d878267d57c3cf1b38d91b71af6686408bbca6a"
|
||||||
|
dependencies = [
|
||||||
|
"heck",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap_lex"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "colorchoice"
|
||||||
|
version = "1.0.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "colored"
|
||||||
|
version = "3.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "faf9468729b8cbcea668e36183cb69d317348c2e08e994829fb56ebfdfbaac34"
|
||||||
|
dependencies = [
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "heck"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hermit-abi"
|
||||||
|
version = "0.5.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "is_terminal_polyfill"
|
||||||
|
version = "1.70.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libc"
|
||||||
|
version = "0.2.183"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memchr"
|
||||||
|
version = "2.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ntapi"
|
||||||
|
version = "0.4.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c3b335231dfd352ffb0f8017f3b6027a4917f7df785ea2143d8af2adc66980ae"
|
||||||
|
dependencies = [
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num_cpus"
|
||||||
|
version = "1.17.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b"
|
||||||
|
dependencies = [
|
||||||
|
"hermit-abi",
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "objc2-core-foundation"
|
||||||
|
version = "0.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "objc2-io-kit"
|
||||||
|
version = "0.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "33fafba39597d6dc1fb709123dfa8289d39406734be322956a69f0931c73bb15"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"objc2-core-foundation",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "once_cell_polyfill"
|
||||||
|
version = "1.70.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.106"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "1.0.45"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "slimefetch"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"clap",
|
||||||
|
"colored",
|
||||||
|
"num_cpus",
|
||||||
|
"sysinfo",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "strsim"
|
||||||
|
version = "0.11.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "2.0.117"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sysinfo"
|
||||||
|
version = "0.38.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "92ab6a2f8bfe508deb3c6406578252e491d299cbbf3bc0529ecc3313aee4a52f"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"memchr",
|
||||||
|
"ntapi",
|
||||||
|
"objc2-core-foundation",
|
||||||
|
"objc2-io-kit",
|
||||||
|
"windows",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-ident"
|
||||||
|
version = "1.0.24"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "utf8parse"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi"
|
||||||
|
version = "0.3.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||||
|
dependencies = [
|
||||||
|
"winapi-i686-pc-windows-gnu",
|
||||||
|
"winapi-x86_64-pc-windows-gnu",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-i686-pc-windows-gnu"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-x86_64-pc-windows-gnu"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows"
|
||||||
|
version = "0.62.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "527fadee13e0c05939a6a05d5bd6eec6cd2e3dbd648b9f8e447c6518133d8580"
|
||||||
|
dependencies = [
|
||||||
|
"windows-collections",
|
||||||
|
"windows-core",
|
||||||
|
"windows-future",
|
||||||
|
"windows-numerics",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-collections"
|
||||||
|
version = "0.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "23b2d95af1a8a14a3c7367e1ed4fc9c20e0a26e79551b1454d72583c97cc6610"
|
||||||
|
dependencies = [
|
||||||
|
"windows-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-core"
|
||||||
|
version = "0.62.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb"
|
||||||
|
dependencies = [
|
||||||
|
"windows-implement",
|
||||||
|
"windows-interface",
|
||||||
|
"windows-link",
|
||||||
|
"windows-result",
|
||||||
|
"windows-strings",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-future"
|
||||||
|
version = "0.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e1d6f90251fe18a279739e78025bd6ddc52a7e22f921070ccdc67dde84c605cb"
|
||||||
|
dependencies = [
|
||||||
|
"windows-core",
|
||||||
|
"windows-link",
|
||||||
|
"windows-threading",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-implement"
|
||||||
|
version = "0.60.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-interface"
|
||||||
|
version = "0.59.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-link"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-numerics"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6e2e40844ac143cdb44aead537bbf727de9b044e107a0f1220392177d15b0f26"
|
||||||
|
dependencies = [
|
||||||
|
"windows-core",
|
||||||
|
"windows-link",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-result"
|
||||||
|
version = "0.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5"
|
||||||
|
dependencies = [
|
||||||
|
"windows-link",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-strings"
|
||||||
|
version = "0.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091"
|
||||||
|
dependencies = [
|
||||||
|
"windows-link",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-sys"
|
||||||
|
version = "0.61.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
|
||||||
|
dependencies = [
|
||||||
|
"windows-link",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-threading"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3949bd5b99cafdf1c7ca86b43ca564028dfe27d66958f2470940f73d86d75b37"
|
||||||
|
dependencies = [
|
||||||
|
"windows-link",
|
||||||
|
]
|
||||||
10
Cargo.toml
Normal file
10
Cargo.toml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
[package]
|
||||||
|
name = "slimefetch"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
clap = { version = "4.6.0", features = ["derive"] }
|
||||||
|
colored = "3.1.1"
|
||||||
|
num_cpus = "1.17.0"
|
||||||
|
sysinfo = "0.38.4"
|
||||||
166
src/benchmark.rs
Normal file
166
src/benchmark.rs
Normal file
@@ -0,0 +1,166 @@
|
|||||||
|
use std::{
|
||||||
|
sync::{
|
||||||
|
Arc, Mutex,
|
||||||
|
atomic::{AtomicUsize, Ordering},
|
||||||
|
},
|
||||||
|
thread,
|
||||||
|
time::{Duration, Instant},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Factor determining how many times the calculation runs in the multi-threaded test.
|
||||||
|
pub const MULTI_THREAD_LOAD_FACTOR: usize = 32;
|
||||||
|
|
||||||
|
pub struct BenchmarkResults {
|
||||||
|
pub duration: Duration,
|
||||||
|
pub primes_found: u64,
|
||||||
|
pub score: u64,
|
||||||
|
pub batch_count: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn run_benchmark_singlethread(prime_limit: u64) -> BenchmarkResults {
|
||||||
|
let start_time = Instant::now();
|
||||||
|
let primes_found = calculate_primes(1, prime_limit);
|
||||||
|
let duration = start_time.elapsed();
|
||||||
|
|
||||||
|
let score = calculate_score(duration, 1, prime_limit);
|
||||||
|
|
||||||
|
BenchmarkResults {
|
||||||
|
duration,
|
||||||
|
primes_found,
|
||||||
|
score,
|
||||||
|
batch_count: 1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn run_benchmark_multithread(prime_limit: u64, jobs: usize) -> BenchmarkResults {
|
||||||
|
let start_time = Instant::now();
|
||||||
|
|
||||||
|
// The total number of calculation batches to perform across all threads
|
||||||
|
let total_jobs_to_process = MULTI_THREAD_LOAD_FACTOR;
|
||||||
|
|
||||||
|
// Atomic counter for distributing jobs to threads without heavy locking
|
||||||
|
let shared_job_index_counter = Arc::new(AtomicUsize::new(0));
|
||||||
|
// Mutex protected accumulator for the total primes found across all threads
|
||||||
|
let shared_total_prime_count = Arc::new(Mutex::new(0));
|
||||||
|
// Vector to store the execution duration of each individual thread
|
||||||
|
let shared_thread_durations = Arc::new(Mutex::new(Vec::new()));
|
||||||
|
|
||||||
|
let mut thread_handles = vec![];
|
||||||
|
|
||||||
|
for _ in 0..jobs {
|
||||||
|
let job_counter_reference = Arc::clone(&shared_job_index_counter);
|
||||||
|
let prime_count_reference = Arc::clone(&shared_total_prime_count);
|
||||||
|
let durations_reference = Arc::clone(&shared_thread_durations);
|
||||||
|
let limit_per_run = prime_limit;
|
||||||
|
|
||||||
|
let handle = thread::spawn(move || {
|
||||||
|
let thread_execution_start = Instant::now();
|
||||||
|
let mut local_thread_prime_count = 0;
|
||||||
|
|
||||||
|
loop {
|
||||||
|
// Fetch the next job index and increment atomically
|
||||||
|
let job_index = job_counter_reference.fetch_add(1, Ordering::Relaxed);
|
||||||
|
|
||||||
|
if job_index >= total_jobs_to_process {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
local_thread_prime_count += calculate_primes(1, limit_per_run);
|
||||||
|
}
|
||||||
|
|
||||||
|
let thread_execution_duration = thread_execution_start.elapsed();
|
||||||
|
|
||||||
|
// Record thread duration
|
||||||
|
durations_reference
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.push(thread_execution_duration);
|
||||||
|
|
||||||
|
// Commit local count to the global sum
|
||||||
|
let mut global_count_lock = prime_count_reference.lock().unwrap();
|
||||||
|
*global_count_lock += local_thread_prime_count;
|
||||||
|
});
|
||||||
|
thread_handles.push(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for all threads to complete
|
||||||
|
for handle in thread_handles {
|
||||||
|
handle.join().unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
let duration = start_time.elapsed();
|
||||||
|
let final_count = *shared_total_prime_count.lock().unwrap();
|
||||||
|
|
||||||
|
// Calculate average time a thread spent working
|
||||||
|
let durations_guard = shared_thread_durations.lock().unwrap();
|
||||||
|
let total_thread_microseconds: u128 = durations_guard.iter().map(|d| d.as_micros()).sum();
|
||||||
|
|
||||||
|
let average_thread_microseconds = if !durations_guard.is_empty() {
|
||||||
|
total_thread_microseconds / durations_guard.len() as u128
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
};
|
||||||
|
let average_thread_duration = Duration::from_micros(average_thread_microseconds as u64);
|
||||||
|
|
||||||
|
// Score normalized by load factor to represent "Speed per unit of work"
|
||||||
|
let score = calculate_score(duration, MULTI_THREAD_LOAD_FACTOR as u64, prime_limit);
|
||||||
|
|
||||||
|
BenchmarkResults {
|
||||||
|
duration,
|
||||||
|
score,
|
||||||
|
primes_found: final_count,
|
||||||
|
batch_count: MULTI_THREAD_LOAD_FACTOR as u64,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Performs the CPU-intensive prime number calculation.
|
||||||
|
pub fn calculate_primes(range_start: u64, range_end: u64) -> u64 {
|
||||||
|
let mut prime_count = 0;
|
||||||
|
let mut current_number = range_start;
|
||||||
|
|
||||||
|
if current_number <= 2 {
|
||||||
|
if range_end >= 2 {
|
||||||
|
prime_count += 1;
|
||||||
|
}
|
||||||
|
current_number = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if current_number % 2 == 0 {
|
||||||
|
current_number += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while current_number <= range_end {
|
||||||
|
if is_number_prime(current_number) {
|
||||||
|
prime_count += 1;
|
||||||
|
}
|
||||||
|
current_number += 2;
|
||||||
|
}
|
||||||
|
prime_count
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Helper function to check primality.
|
||||||
|
pub fn is_number_prime(number: u64) -> bool {
|
||||||
|
if number <= 1 {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let search_limit = (number as f64).sqrt() as u64;
|
||||||
|
|
||||||
|
for i in (3..=search_limit).step_by(2) {
|
||||||
|
if number % i == 0 {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Calculates a score based on work done divided by time taken.
|
||||||
|
pub fn calculate_score(duration: Duration, batch_multiplier: u64, prime_limit: u64) -> u64 {
|
||||||
|
let microseconds = duration.as_micros() as u64;
|
||||||
|
|
||||||
|
if microseconds == 0 {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
(prime_limit * batch_multiplier * 10_000) / microseconds
|
||||||
|
}
|
||||||
18
src/lib.rs
Normal file
18
src/lib.rs
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
// use colored::Colorize;
|
||||||
|
|
||||||
|
mod benchmark;
|
||||||
|
mod slimes;
|
||||||
|
|
||||||
|
pub fn application_header() -> &'static str {
|
||||||
|
let ascii_art = r#"
|
||||||
|
.---.
|
||||||
|
.' '. < CPU SLIME >
|
||||||
|
/ ^ ^ \
|
||||||
|
: v : (Benchmarking)
|
||||||
|
| |
|
||||||
|
\ /
|
||||||
|
'._____.'
|
||||||
|
"#;
|
||||||
|
// println!("{}", ascii_art.bright_green().bold());
|
||||||
|
ascii_art
|
||||||
|
}
|
||||||
84
src/main.rs
Normal file
84
src/main.rs
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
use clap::Parser;
|
||||||
|
use colored::Colorize;
|
||||||
|
use slimefetch::application_header;
|
||||||
|
|
||||||
|
mod benchmark;
|
||||||
|
use crate::benchmark::{BenchmarkResults, run_benchmark_multithread, run_benchmark_singlethread};
|
||||||
|
|
||||||
|
#[derive(Parser, Debug)]
|
||||||
|
#[command(author, version, about, long_about = None)]
|
||||||
|
pub struct Cli {
|
||||||
|
/// Skip CPU benchmark
|
||||||
|
#[arg(short, long)]
|
||||||
|
pub skip_benchmark: bool,
|
||||||
|
|
||||||
|
/// Benchmark: Upper limit for prime calculation (higher number = longer test)
|
||||||
|
#[arg(short, long, default_value_t = 500_000)]
|
||||||
|
pub prime_limit: u64,
|
||||||
|
|
||||||
|
/// Benchmark: Enforce cpu thread amount to use.
|
||||||
|
/// Defaults to detected cpu core count.
|
||||||
|
#[arg(short, long)]
|
||||||
|
pub jobs: Option<usize>,
|
||||||
|
|
||||||
|
/// Enable verbose output logging
|
||||||
|
#[arg(short, long)]
|
||||||
|
pub verbose: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let cli = Cli::parse();
|
||||||
|
|
||||||
|
println!("{}", application_header().bright_blue());
|
||||||
|
|
||||||
|
let logical_core_count = match cli.jobs {
|
||||||
|
Some(j) => j,
|
||||||
|
None => num_cpus::get(),
|
||||||
|
};
|
||||||
|
|
||||||
|
print_section_header("Single Threaded CPU Benchmark");
|
||||||
|
let singlethread_benchmark = run_benchmark_singlethread(cli.prime_limit);
|
||||||
|
print_detailed_result(&singlethread_benchmark);
|
||||||
|
print_section_header("Multi Threaded CPU Benchmark");
|
||||||
|
let multithread_benchmark = run_benchmark_multithread(cli.prime_limit, logical_core_count);
|
||||||
|
print_detailed_result(&multithread_benchmark);
|
||||||
|
|
||||||
|
let multi_thread_speedup_ratio = if singlethread_benchmark.score > 0 {
|
||||||
|
multithread_benchmark.score / singlethread_benchmark.score
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
|
let scaling_color_formatter =
|
||||||
|
if multi_thread_speedup_ratio as f64 > (logical_core_count as f64 * 0.7) {
|
||||||
|
|s: String| s.green()
|
||||||
|
} else {
|
||||||
|
|s: String| s.yellow()
|
||||||
|
};
|
||||||
|
|
||||||
|
println!(
|
||||||
|
"Parallel Scaling : {}",
|
||||||
|
scaling_color_formatter(format!("{:.2}x", multi_thread_speedup_ratio)).bold()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn print_section_header(title_text: &str) {
|
||||||
|
println!(
|
||||||
|
"{}",
|
||||||
|
format!("[ {} ]", title_text).white().bold().underline()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn print_detailed_result(results: &BenchmarkResults) {
|
||||||
|
println!(
|
||||||
|
" Batch Count : {} batch{}",
|
||||||
|
results.batch_count,
|
||||||
|
if results.batch_count > 1 { "es" } else { "" }
|
||||||
|
);
|
||||||
|
println!(" Total Duration : {:.4}s", results.duration.as_secs_f64());
|
||||||
|
println!(" Primes Found : {}", results.primes_found);
|
||||||
|
println!(
|
||||||
|
" Calculated Score: {}",
|
||||||
|
format!("{}", results.score).green().bold()
|
||||||
|
);
|
||||||
|
}
|
||||||
18
src/slimes.rs
Normal file
18
src/slimes.rs
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
use colored::Color;
|
||||||
|
use colored::Colorize;
|
||||||
|
|
||||||
|
trait Slime {
|
||||||
|
fn label(&self) -> String;
|
||||||
|
fn value(&self) -> String;
|
||||||
|
fn icon(&self) -> String;
|
||||||
|
fn color(&self) -> Color;
|
||||||
|
|
||||||
|
fn print(&self) {
|
||||||
|
println!(
|
||||||
|
"{} {:<12} {}",
|
||||||
|
self.icon().color(self.color()),
|
||||||
|
format!("{}:", self.label()).bold().color(self.color()),
|
||||||
|
self.value().white()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user