use std::time::Instant;
fn main() {
let goal_num = 1 << 25;
let args: Vec<String> = std::env::args().collect();
let mode = args.get(1).map(String::as_str).unwrap_or("help");
let start = Instant::now();
match mode {
"para" => parallel::para(goal_num),
"nopara" => parallel::nopara(goal_num),
_ => eprintln!("사용법 : cargo run -- [para|nopara]"),
}
println!("end {goal_num} numbers");
let elapsed = start.elapsed();
println!("걸린 시간: {:?}", elapsed);
}
main 스크립트이다. 표준 라이브러리로 시간을 측정하고, cargo run 뒤에 매개변수를 받아 병렬과 no병렬을 구분한다.
use rayon::prelude::*;
pub fn para(goal_num: u128) {
println!("parallel start");
(3..goal_num)
.into_par_iter()
.filter(|x| x % 2 == 1)
.for_each(|i| {
if !crate::calculation(i){
println!("false!!!");
};
});
}
pub fn nopara(goal_num: u128){
println!("not parallel start");
for n in (3..goal_num).step_by(2){
if !crate::calculation(n){
println!("false!!!");
break;
};
}
}
pub fn calculation(i: u128) ->bool{
let mut n = i;
while n >= i {
if n % 2 == 0 {
n = n >> 1;
} else {
n = (n << 1) + n + 1;
}
}
true
}
lib 스크립트이다. calculation은 공용이고, para/nopara로 나뉜다.
Taery@YellowMac: ~/Collatz_Conjecture/parallel main!
$ cargo run -- nopara [22:56:21]
Compiling parallel v0.1.0 (/Users/Taery/Collatz_Conjecture/parallel)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.19s
Running `target/debug/parallel nopara`
not parallel start
end 33554432 numbers
걸린 시간: 2.475524208s
Taery@YellowMac: ~/Collatz_Conjecture/parallel main!
$ cargo run -- para [23:07:59]
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.05s
Running `target/debug/parallel para`
parallel start
end 33554432 numbers
걸린 시간: 613.375291ms
no병렬은 2^25까지의 숫자 검사하는데 2.475524208s,
병렬은 613.375291ms 걸렸다. 4배 차이가 난다.(맥북 M2에어)
M2에어가 8코어지만, 실제 계산에 쓰이는건 4코어 정도라고 하니 대략 맞는 시간인것 같다.
--release컴파일로 실행 시간을 줄일 수 있는데, 일단 하지 않았다.
러스트 컴파일러가, 결과값에 관련 없는 코드는 실행을 안 할 수 있다고 한다.(dead code)
지금도 코드가 죽었는지는 정확히 모르겠다. 확실히 하는 방법이 있다고 하니 시도할 것이다.
dead code를 확실히 해결하고, cpu에서 할 수 있는 최적화를 더 시도해본 뒤 gpu로 넘어가야겠다.
러스트 책을 구매했다. 러스트의 문법, 작명 등에서 잘 만들었다는 생각이 든다.
제대로 공부를 해야할 언어인 것 같다.