simd opti
This commit is contained in:
194
src/benchmark.rs
194
src/benchmark.rs
@ -3,7 +3,8 @@ use crate::code::{CodeTopology, GenerationMethod, LdpcCode, LdpcParams};
|
||||
use crate::decoder::{build_decoder, DecoderConfig, DecoderMethod};
|
||||
use crate::encoder::{build_encoder, EncodingMethod};
|
||||
use crate::Result as LdpcResult;
|
||||
use rand::{Rng, SeedableRng};
|
||||
use rand::Rng;
|
||||
use rayon::prelude::*;
|
||||
use std::fs::File;
|
||||
use std::io::{Read, Write};
|
||||
use std::path::Path;
|
||||
@ -37,13 +38,10 @@ pub fn run_simulation(mut code: LdpcCode) -> LdpcResult<()> {
|
||||
}
|
||||
);
|
||||
|
||||
println!("\n[*] Étape 2 : Extraction de G^T et Instanciation de l'Encodeur");
|
||||
println!("\n[*] Étape 2 : Instanciation de l'Encodeur (SIMD Bit-Packing)");
|
||||
let start_enc = Instant::now();
|
||||
let encoder = build_encoder(&mut code, EncodingMethod::Systematic)?;
|
||||
println!(
|
||||
" - Forme systématique calculée en {:.2?}",
|
||||
start_enc.elapsed()
|
||||
);
|
||||
println!(" - Encodeur prêt en {:.2?}", start_enc.elapsed());
|
||||
|
||||
println!("\n[*] Étape 3 : Instanciation des Décodeurs sur Graphe");
|
||||
let config = DecoderConfig {
|
||||
@ -62,12 +60,11 @@ pub fn run_simulation(mut code: LdpcCode) -> LdpcResult<()> {
|
||||
let dec_bf = build_decoder(&code, DecoderMethod::BitFlipping, config.clone());
|
||||
println!(" - Moteurs prêts : Sum-Product, Min-Sum (α=0.8), Bit-Flipping");
|
||||
|
||||
let snr_range = [1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0];
|
||||
let n_trials = 100;
|
||||
let mut rng = rand::rngs::StdRng::seed_from_u64(42);
|
||||
let snr_range = [1.0, 1.25, 1.5, 1.75, 2.0, 2.25, 2.5, 3.0, 3.5, 4.0];
|
||||
let n_trials = 1000;
|
||||
|
||||
println!(
|
||||
"\n[*] Étape 4 : Simulation sur Canal AWGN ({} trames par SNR)",
|
||||
"\n[*] Étape 4 : Simulation sur Canal AWGN ({} trames par SNR, Multi-threadé)",
|
||||
n_trials
|
||||
);
|
||||
println!("{:-<115}", "");
|
||||
@ -86,6 +83,67 @@ pub fn run_simulation(mut code: LdpcCode) -> LdpcResult<()> {
|
||||
|
||||
for &snr in &snr_range {
|
||||
let channel = AwgnChannel::new(snr, code.rate())?;
|
||||
|
||||
let results: Vec<_> = (0..n_trials)
|
||||
.into_par_iter()
|
||||
.map(|_| {
|
||||
let mut rng = rand::thread_rng();
|
||||
|
||||
let message: Vec<u8> = (0..code.k()).map(|_| rng.gen::<u8>() & 1).collect();
|
||||
let codeword = encoder.encode(&message).unwrap();
|
||||
let received_llr = channel.transmit(&codeword, &mut rng);
|
||||
|
||||
let mut t_sp_f = 0;
|
||||
let mut t_sp_b = 0;
|
||||
let mut t_ms_f = 0;
|
||||
let mut t_ms_b = 0;
|
||||
let mut t_bf_f = 0;
|
||||
let mut t_bf_b = 0;
|
||||
|
||||
// SP
|
||||
let res_sp = dec_sp.decode(&received_llr);
|
||||
if let Some(decoded) = res_sp.codeword() {
|
||||
let errs = count_bit_errors(&codeword, decoded);
|
||||
if errs > 0 {
|
||||
t_sp_f = 1;
|
||||
t_sp_b = errs;
|
||||
}
|
||||
} else {
|
||||
t_sp_f = 1;
|
||||
t_sp_b = code.n();
|
||||
}
|
||||
|
||||
// MS
|
||||
let res_ms = dec_ms.decode(&received_llr);
|
||||
if let Some(decoded) = res_ms.codeword() {
|
||||
let errs = count_bit_errors(&codeword, decoded);
|
||||
if errs > 0 {
|
||||
t_ms_f = 1;
|
||||
t_ms_b = errs;
|
||||
}
|
||||
} else {
|
||||
t_ms_f = 1;
|
||||
t_ms_b = code.n();
|
||||
}
|
||||
|
||||
// BF
|
||||
let res_bf = dec_bf.decode(&received_llr);
|
||||
if let Some(decoded) = res_bf.codeword() {
|
||||
let errs = count_bit_errors(&codeword, decoded);
|
||||
if errs > 0 {
|
||||
t_bf_f = 1;
|
||||
t_bf_b = errs;
|
||||
}
|
||||
} else {
|
||||
t_bf_f = 1;
|
||||
t_bf_b = code.n();
|
||||
}
|
||||
|
||||
(t_sp_f, t_sp_b, t_ms_f, t_ms_b, t_bf_f, t_bf_b)
|
||||
})
|
||||
.collect();
|
||||
|
||||
// Agrégation
|
||||
let mut err_sp_frames = 0;
|
||||
let mut err_sp_bits = 0;
|
||||
let mut err_ms_frames = 0;
|
||||
@ -93,49 +151,13 @@ pub fn run_simulation(mut code: LdpcCode) -> LdpcResult<()> {
|
||||
let mut err_bf_frames = 0;
|
||||
let mut err_bf_bits = 0;
|
||||
|
||||
for _ in 0..n_trials {
|
||||
let message: Vec<u8> = (0..code.k()).map(|_| rng.gen::<u8>() & 1).collect();
|
||||
let codeword = encoder.encode(&message)?;
|
||||
let received_llr = channel.transmit(&codeword, &mut rng);
|
||||
|
||||
// SP
|
||||
let res_sp = dec_sp.decode(&received_llr);
|
||||
if let Some(decoded) = res_sp.codeword() {
|
||||
let errs = count_bit_errors(&codeword, decoded);
|
||||
if errs > 0 {
|
||||
err_sp_frames += 1;
|
||||
err_sp_bits += errs;
|
||||
}
|
||||
} else {
|
||||
err_sp_frames += 1;
|
||||
err_sp_bits += code.n();
|
||||
}
|
||||
|
||||
// MS
|
||||
let res_ms = dec_ms.decode(&received_llr);
|
||||
if let Some(decoded) = res_ms.codeword() {
|
||||
let errs = count_bit_errors(&codeword, decoded);
|
||||
if errs > 0 {
|
||||
err_ms_frames += 1;
|
||||
err_ms_bits += errs;
|
||||
}
|
||||
} else {
|
||||
err_ms_frames += 1;
|
||||
err_ms_bits += code.n();
|
||||
}
|
||||
|
||||
// BF
|
||||
let res_bf = dec_bf.decode(&received_llr);
|
||||
if let Some(decoded) = res_bf.codeword() {
|
||||
let errs = count_bit_errors(&codeword, decoded);
|
||||
if errs > 0 {
|
||||
err_bf_frames += 1;
|
||||
err_bf_bits += errs;
|
||||
}
|
||||
} else {
|
||||
err_bf_frames += 1;
|
||||
err_bf_bits += code.n();
|
||||
}
|
||||
for res in results {
|
||||
err_sp_frames += res.0;
|
||||
err_sp_bits += res.1;
|
||||
err_ms_frames += res.2;
|
||||
err_ms_bits += res.3;
|
||||
err_bf_frames += res.4;
|
||||
err_bf_bits += res.5;
|
||||
}
|
||||
|
||||
let total_bits = (n_trials * code.n()) as f64;
|
||||
@ -162,39 +184,39 @@ fn count_bit_errors(transmitted: &[u8], decoded: &[u8]) -> usize {
|
||||
.count()
|
||||
}
|
||||
|
||||
pub fn generate_valid_code(
|
||||
n: usize,
|
||||
k: usize,
|
||||
wc: usize,
|
||||
wr: usize,
|
||||
generation_method: GenerationMethod,
|
||||
) -> LdpcResult<LdpcCode> {
|
||||
let mut attempt = 0;
|
||||
let start_gen = Instant::now();
|
||||
loop {
|
||||
attempt += 1;
|
||||
let params = LdpcParams {
|
||||
n,
|
||||
k,
|
||||
topology: CodeTopology::Regular { wc, wr },
|
||||
generation: generation_method.clone(),
|
||||
seed: Some(rand::random()),
|
||||
};
|
||||
|
||||
if let Ok(mut code) = LdpcCode::new(params) {
|
||||
if code.compute_systematic_form().is_ok() {
|
||||
if attempt > 1 {
|
||||
println!(
|
||||
" -> Matrice inversible obtenue après {} tentatives.",
|
||||
attempt
|
||||
);
|
||||
}
|
||||
println!(" - Génération : Terminée en {:.2?}", start_gen.elapsed());
|
||||
return Ok(code);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// pub fn generate_valid_code(
|
||||
// n: usize,
|
||||
// k: usize,
|
||||
// wc: usize,
|
||||
// wr: usize,
|
||||
// generation_method: GenerationMethod,
|
||||
// ) -> LdpcResult<LdpcCode> {
|
||||
// let mut attempt = 0;
|
||||
// let start_gen = Instant::now();
|
||||
// loop {
|
||||
// attempt += 1;
|
||||
// let params = LdpcParams {
|
||||
// n,
|
||||
// k,
|
||||
// topology: CodeTopology::Regular { wc, wr },
|
||||
// generation: generation_method.clone(),
|
||||
// seed: Some(rand::random()),
|
||||
// };
|
||||
//
|
||||
// if let Ok(mut code) = LdpcCode::new(params) {
|
||||
// if code.compute_systematic_form().is_ok() {
|
||||
// if attempt > 1 {
|
||||
// println!(
|
||||
// " -> Matrice inversible obtenue après {} tentatives.",
|
||||
// attempt
|
||||
// );
|
||||
// }
|
||||
// println!(" - Génération : Terminée en {:.2?}", start_gen.elapsed());
|
||||
// return Ok(code);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
pub fn get_or_generate_cached_code(
|
||||
n: usize,
|
||||
|
||||
Reference in New Issue
Block a user