瀏覽代碼

Working but still ugly.

themultiplexer 7 年之前
父節點
當前提交
1b3598eff0
共有 4 個檔案被更改,包括 157 行新增57 行删除
  1. 4
    4
      hw8/task1/src/lib.rs
  2. 136
    46
      hw8/task1/src/main.rs
  3. 17
    0
      hw8/task1/src/tests/mod.rs
  4. 0
    7
      hw8/task1/src/unit_test.rs

+ 4
- 4
hw8/task1/src/lib.rs 查看文件

@@ -2,7 +2,6 @@ extern crate sha2;
2 2
 #[cfg(feature = "SHA2")]
3 3
 use self::sha2::Sha256;
4 4
 
5
-
6 5
 pub struct Sha256;
7 6
 
8 7
 pub trait Hasher {
@@ -17,7 +16,6 @@ pub trait HashResult {
17 16
     fn size() -> usize;
18 17
 }
19 18
 
20
-
21 19
 impl Hasher for Sha256 {
22 20
     type Output = [u8; 32];
23 21
 
@@ -110,9 +108,11 @@ pub fn verify_product(base: usize, number: usize, difficulty: &String) -> Option
110 108
     let hash = Sha256::hash(bytes).hex();
111 109
 
112 110
     if hash.ends_with(difficulty) {
113
-        return Some(Solution{ number: number, hash: hash,});
111
+        return Some(Solution {
112
+            number: number,
113
+            hash: hash,
114
+        });
114 115
     }
115 116
 
116 117
     None
117 118
 }
118
-

+ 136
- 46
hw8/task1/src/main.rs 查看文件

@@ -4,24 +4,35 @@ extern crate time;
4 4
 extern crate task1;
5 5
 extern crate sys_info;
6 6
 
7
-use std::sync::mpsc::channel;
7
+mod tests;
8
+
9
+use std::sync::mpsc::{Sender, channel};
8 10
 use time::get_time;
9 11
 use clap::App;
10
-use std::{process, thread};
11
-use task1::verify_product;
12
+use time::Duration;
12 13
 use std::sync::Arc;
14
+use std::sync::atomic::AtomicBool;
15
+use std::sync::atomic::Ordering::Relaxed;
16
+use std::{process, thread};
17
+use task1::{Solution, verify_product};
18
+
13 19
 
14 20
 pub fn main() {
21
+    // Lade Commandline Einstellungen aus YAML-Datei
15 22
     let yaml = load_yaml!("cli.yml");
16 23
     let matches = App::from_yaml(yaml).get_matches();
24
+
25
+    // Speichere alle Argumente in Variablen
26
+    // Falls ein Wert für ein Argument nicht existiert, lade einen default-Wert
17 27
     let base = matches.value_of("base").unwrap_or("1");
18
-    let diff = Arc::new(matches.value_of("difficulty").unwrap_or("1").to_string());
28
+    let diff = Arc::new(String::from(matches.value_of("difficulty").unwrap_or("1")));
19 29
     let cpus = sys_info::cpu_num().unwrap_or(1).to_string();
20 30
     let threads = matches.value_of("threads").unwrap_or(&cpus);
21 31
     let sync = matches.is_present("sync");
32
+    let special = matches.value_of("special").unwrap_or("1").parse::<usize>().unwrap_or(1);
22 33
     let wait = matches.is_present("wait");
23
-    let verbosity = matches.occurrences_of("verbose"); 
24
-    
34
+    let verbosity = matches.occurrences_of("verbose");
35
+
25 36
     let mut time_measurement = false;
26 37
 
27 38
     // Falls irgendein Zeichen nicht hexadezimal ist, breche ab.
@@ -37,9 +48,13 @@ pub fn main() {
37 48
         }
38 49
     }
39 50
 
40
-    if verbosity >= 1 {
51
+    // Gebe Headerinfos aus, wenn mindestens ein 'v' vorkommt
52
+    if verbosity > 0 {
41 53
         println!("--------------------------------------------");
42
-        println!("Container: \"{}\"", sys_info::hostname().unwrap_or("-".to_string()));
54
+        println!(
55
+            "Container     : \"{}\"",
56
+            sys_info::hostname().unwrap_or(String::from("-"))
57
+        );
43 58
         println!("Physical CPUs : {}", sys_info::cpu_num().unwrap_or(0));
44 59
         println!("Logical CPUs  : {}", sys_info::cpu_num().unwrap_or(0));
45 60
         println!("CPU Speed     : {}", sys_info::cpu_speed().unwrap_or(0));
@@ -48,56 +63,71 @@ pub fn main() {
48 63
         println!("--------------------------------------------");
49 64
     }
50 65
 
66
+    // Versuche Strings der Basis und Threadanzahl zu usize zu parsen
67
+    // Anderenfalls
51 68
     match (base.parse::<usize>(), threads.parse::<usize>()) {
52 69
         (Ok(b), Ok(t)) => {
53 70
             println!("Please wait...");
54 71
 
55
-            if verbosity >= 1 {
72
+            if verbosity > 0 {
56 73
                 println!("Searching with {} threads", t);
57 74
             }
58 75
 
59
-            let start = get_time();
60
-            let max = <usize>::max_value();
76
+            let total_start = get_time();
77
+
61 78
             let mut children = vec![];
62 79
 
63
-            let (tx, rx) = channel();
64
-            let mut found = &false;
80
+            let (solution_tx, solution_rx) = channel();
81
+            let (timing_tx, timing_rx) = channel();
65 82
 
66
-            for i in 0..t {
67
-                let d = diff.clone();
68
-                let tx = tx.clone();
69
-                
70
-                children.push(thread::spawn(move || {
71
-                    let mut n = i;
72
-                    while n < max {
83
+            let found = Arc::new(AtomicBool::new(false));
84
+            let m = time_measurement && verbosity > 0;
73 85
 
74
-                        if n % (100000 + i)  == 0 {
75
-                            println!("Thread {}: {}", i, n);
76
-                        }
86
+            if t > 1 {
77 87
 
78
-                        if *found && sync {
79
-                            return n; 
80
-                        }
88
+                for i in 0..t {
89
+                    let diff = diff.clone();
90
+                    let solution_tx = solution_tx.clone();
91
+                    let timing_tx = timing_tx.clone();
92
+                    let found = found.clone();
81 93
 
82
-                        if let Some(solution) = verify_product(b, n, &d) {
83
-                            *found = true;
84
-                            tx.send(solution).unwrap();
85
-                            if sync {
86
-                                break;
87
-                            }
88
-                        }
89
-                        n += t;
90
-                    }
91
-                    n
92
-                }));
94
+                    children.push(thread::spawn(move || {
95
+
96
+                        search_hash(
97
+                            &diff,
98
+                            b,
99
+                            i,
100
+                            t,
101
+                            sync,
102
+                            found,
103
+                            special,
104
+                            solution_tx,
105
+                            timing_tx,
106
+                            m,
107
+                        )
108
+                    }));
109
+                }
110
+            } else {
111
+                search_hash(
112
+                    &diff,
113
+                    b,
114
+                    0,
115
+                    1,
116
+                    sync,
117
+                    found,
118
+                    special,
119
+                    solution_tx,
120
+                    timing_tx,
121
+                    m,
122
+                )
93 123
             }
94 124
 
95
-            match rx.recv() {
125
+            match solution_rx.recv() {
96 126
                 Ok(sol) => {
97
-                    let end = get_time();
127
+                    let total_end = get_time();
98 128
                     println!("Number: {} --> hash: {}", sol.number, sol.hash);
99
-                    if time_measurement {
100
-                        let diff = end - start;
129
+                    if time_measurement && verbosity == 0 {
130
+                        let diff = total_end - total_start;
101 131
                         let s = diff.num_seconds();
102 132
                         let ms = diff.num_milliseconds();
103 133
                         let us = diff.num_microseconds().unwrap_or(ms * 1000);
@@ -107,13 +137,34 @@ pub fn main() {
107 137
                 Err(_) => {}
108 138
             }
109 139
 
110
-            if wait {
111
-                for child in children {
112
-                    let loops = child.join();
113
-                    println!("Loops: {}", loops.unwrap());
140
+            let mut sum_loops = 0usize;
141
+            let mut sum_time: Duration = Duration::zero();
142
+
143
+            for child in children {
144
+
145
+                if time_measurement && verbosity > 0 {
146
+                    match timing_rx.recv() {
147
+                        Ok(stats) => {
148
+                            sum_time = sum_time + stats.0;
149
+                            sum_loops += stats.1;
150
+                        }
151
+                        Err(_) => {}
152
+                    }
153
+                }
154
+
155
+                if wait {
156
+                    let _ = child.join();
114 157
                 }
115 158
             }
116
-        
159
+
160
+            if time_measurement && verbosity > 0 {
161
+                println!("Sum Loops in Producers:       {}", sum_loops);
162
+                let s = sum_time.num_seconds();
163
+                let ms = sum_time.num_milliseconds();
164
+                let us = sum_time.num_microseconds().unwrap_or(ms * 1000);
165
+                println!("Sum Duration in Producers:    {}s / {}ms / {}us", s, ms, us);
166
+            }
167
+
117 168
         }
118 169
         (_, Err(_)) => {
119 170
             println!("Number of threads is not integer.");
@@ -125,3 +176,42 @@ pub fn main() {
125 176
         }
126 177
     };
127 178
 }
179
+
180
+pub fn search_hash(
181
+    hash: &String,
182
+    base: usize,
183
+    current: usize,
184
+    total: usize,
185
+    sync: bool,
186
+    found: Arc<AtomicBool>,
187
+    special: usize,
188
+    solution_tx: Sender<Solution>,
189
+    timing_tx: Sender<(Duration, usize)>,
190
+    measure: bool,
191
+) {
192
+    let max = <usize>::max_value();
193
+    let mut n = current;
194
+
195
+    let thread_start = get_time();
196
+    while n < max {
197
+
198
+        if n % special == 0 && found.load(Relaxed) {
199
+            break;
200
+        }
201
+
202
+        if let Some(solution) = verify_product(base, n, hash) {
203
+            if sync {
204
+                found.store(true, Relaxed);
205
+            }
206
+
207
+            let _ = solution_tx.send(solution);
208
+            break;
209
+        }
210
+        n += total;
211
+    }
212
+
213
+    if measure {
214
+        let thread_end = get_time();
215
+        let _ = timing_tx.send((thread_end - thread_start, n));
216
+    }
217
+}

+ 17
- 0
hw8/task1/src/tests/mod.rs 查看文件

@@ -0,0 +1,17 @@
1
+#[cfg(test)]
2
+mod tests {
3
+    use search_hash;
4
+
5
+    #[test]
6
+    fn test_faulty_diff() {
7
+        search_hash()
8
+    }
9
+
10
+
11
+    fn test_hash() {
12
+        assert_eq!(
13
+            hash("test".as_bytes()).hex(),
14
+            "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08"
15
+        );
16
+    }
17
+}

+ 0
- 7
hw8/task1/src/unit_test.rs 查看文件

@@ -1,7 +0,0 @@
1
-#[test]
2
-fn test_hash() {
3
-    assert_eq!(
4
-        Sha256::hash("test".as_bytes()).hex(),
5
-        "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08"
6
-    );
7
-}

Loading…
取消
儲存