better practice for callback in POWSolver.solve_blocking

This commit is contained in:
b1ek 2023-08-02 23:29:06 +10:00
parent fd90500b83
commit 5d2ff3712b
Signed by: blek
GPG Key ID: 14546221E3595D0C
4 changed files with 191 additions and 23 deletions

View File

@ -33,6 +33,19 @@ dependencies = [
"inout",
]
[[package]]
name = "console"
version = "0.15.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c926e00cc70edefdc64d3a5ff31cc65bb97a3460097762bd23afb4d8145fccf8"
dependencies = [
"encode_unicode",
"lazy_static",
"libc",
"unicode-width",
"windows-sys",
]
[[package]]
name = "cpufeatures"
version = "0.2.9"
@ -63,6 +76,12 @@ dependencies = [
"subtle",
]
[[package]]
name = "encode_unicode"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
[[package]]
name = "generic-array"
version = "0.14.7"
@ -93,6 +112,19 @@ dependencies = [
"digest",
]
[[package]]
name = "indicatif"
version = "0.17.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ff8cc23a7393a397ed1d7f56e6365cba772aba9f9912ab968b03043c395d057"
dependencies = [
"console",
"instant",
"number_prefix",
"portable-atomic",
"unicode-width",
]
[[package]]
name = "inout"
version = "0.1.3"
@ -102,12 +134,33 @@ dependencies = [
"generic-array",
]
[[package]]
name = "instant"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
dependencies = [
"cfg-if",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.147"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
[[package]]
name = "number_prefix"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3"
[[package]]
name = "password-hash"
version = "0.5.0"
@ -129,6 +182,12 @@ dependencies = [
"hmac",
]
[[package]]
name = "portable-atomic"
version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f32154ba0af3a075eefa1eda8bb414ee928f62303a54ea85b8d6638ff1a6ee9e"
[[package]]
name = "powlib"
version = "0.1.0"
@ -141,6 +200,7 @@ dependencies = [
name = "powlib-multithreaded-example"
version = "0.0.1"
dependencies = [
"indicatif",
"powlib",
]
@ -224,6 +284,12 @@ version = "1.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"
[[package]]
name = "unicode-width"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
[[package]]
name = "version_check"
version = "0.9.4"
@ -235,3 +301,69 @@ name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "windows-sys"
version = "0.45.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-targets"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
[[package]]
name = "windows_aarch64_msvc"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
[[package]]
name = "windows_i686_gnu"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
[[package]]
name = "windows_i686_msvc"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
[[package]]
name = "windows_x86_64_gnu"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
[[package]]
name = "windows_x86_64_msvc"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"

View File

@ -5,4 +5,5 @@ edition = "2021"
publish = false
[dependencies]
indicatif = "0.17.5"
powlib = { path = '../..' }

View File

@ -1,8 +1,25 @@
use std::time::Instant;
use indicatif::ProgressBar;
use powlib::{gen::{POWRange, POWChallenge}, solver::POWSolver};
fn main() {
let challenge = POWChallenge::make(POWRange::new(0, 20480));
let challenge = POWChallenge::make(POWRange::new(0, 204800));
let mut solver = POWSolver::new(challenge);
println!("Found {} with 8 threads", solver.solve_blocking(8, Some(|x| println!("{x}"))));
let mut count = 0;
let progess = ProgressBar::new(204800);
let thr_progress = progess.clone();
let time = Instant::now();
let result = solver.solve_blocking(16, Some(move |_| {
thr_progress.set_position(count);
count += 1;
}));
progess.finish();
println!("Found {result} in {} ms", time.elapsed().as_secs_f32());
}

View File

@ -1,4 +1,4 @@
use std::{sync::{mpsc, Arc, atomic::{AtomicBool, Ordering}}, thread::{self, JoinHandle}};
use std::{sync::{mpsc, Arc, atomic::{AtomicBool, Ordering}}, thread::{self, JoinHandle}, time::Duration};
use crate::{gen::POWChallenge, num::Num};
@ -8,6 +8,11 @@ pub struct POWSolver {
result: Option<u128>
}
enum SolverThreadMessage {
PlainNumber(u128),
Found(u128)
}
impl POWSolver {
/**
@ -74,8 +79,8 @@ impl POWSolver {
This method also supports callbacks via `Option`
*/
pub fn solve_blocking(self: &mut POWSolver, threads: u8, callback: Option<fn(u128)>) -> u128 {
let (send, recv) = mpsc::sync_channel::<u128>(1);
pub fn solve_blocking(self: &mut POWSolver, threads: u8, mut callback: Option<impl FnMut(u128)>) -> u128 {
let (send, recv) = mpsc::sync_channel::<SolverThreadMessage>(1);
let mut thread_start: u128 = self.challenge.range.min;
let size = self.chunksize(threads);
@ -94,36 +99,49 @@ impl POWSolver {
}
handles.push(
thread::spawn(move || {
for j in thread_start..end {
if stop.load(Ordering::Relaxed) { break }
if callback.is_some() {
callback.unwrap()(j);
}
thread::spawn(move || {
for j in thread_start..end {
if stop.load(Ordering::Relaxed) { break }
if solver.challenge.check(Num::from(j as u128)) {
stop.store(true, Ordering::Relaxed);
send.send(j as u128).unwrap();
}
if solver.challenge.check(Num::from(j as u128)) {
stop.store(true, Ordering::Relaxed);
send.send(SolverThreadMessage::Found(j)).unwrap();
} else {
send.send(SolverThreadMessage::PlainNumber(j)).unwrap();
}
}
)
})
);
thread_start = thread_start + size + 1;
}
let result = recv.recv().unwrap();
stop.load(Ordering::Relaxed);
let mut result = 0;
loop {
let mut all_finished = true;
for handle in handles.iter() {
if !handle.is_finished() {
all_finished = false
let status = recv.recv().unwrap();
match status {
SolverThreadMessage::PlainNumber(num) => {
if callback.is_some() {
callback.as_mut().unwrap()(num);
}
},
SolverThreadMessage::Found(num) => {
result = num;
stop.store(true, Ordering::Relaxed);
break;
}
}
if all_finished { break }
if stop.load(Ordering::Relaxed) {
let mut all_finished = true;
for handle in handles.iter() {
if !handle.is_finished() {
all_finished = false
}
}
if all_finished { break }
}
}
self.result = Some(result);