batch 要来力

This commit is contained in:
shenjack 2024-06-23 21:08:28 +08:00
parent 06777afc80
commit a2e5e8b1ae
Signed by: shenjack
GPG Key ID: 7B1134A979775551
4 changed files with 56 additions and 70 deletions

View File

@ -13,6 +13,8 @@
反正现在在我的 5800x 上能跑到 700E/d (单线程) 了
> 我预计在后面加一下多线程运行的时候加个总计效率
去掉了 `--bench`
## 0.2.15~16
一些提前过滤的东西

View File

@ -1,6 +1,7 @@
use crate::{
evaluate::NamerEvaluater,
name::{Namer, TeamNamer}, Command,
name::{Namer, TeamNamer},
Command,
};
use std::{io::Write, path::PathBuf};
@ -38,52 +39,42 @@ pub struct CacluateConfig {
pub report_interval: u64,
/// 可能的设置指定核心亲和性
pub core_affinity: Option<usize>,
/// 输出文件名
pub out_file: PathBuf,
}
pub fn start_main(cli_arg: Command, out_path: PathBuf) {
if cli_arg.bench {
info!("开始 benchmark");
cli_arg.thread_count = 1;
let mut config = cli_arg.as_cacl_config();
config.core_affinity = Some(1 << cli_arg.pick_core);
set_process_cores(config.core_affinity.unwrap());
cacluate::cacl(config, 1, &out_path);
let mut n = 0;
let mut cores = 0;
if cli_arg.is_single_thread() {
// 单线程运行的时候也是让他放在主线程跑
let config = cli_arg.as_cacl_config(&out_path);
crate::set_process_cores(config.core_affinity.unwrap());
cacl(config, 0);
} else {
let mut n = 0;
let mut cores = 0;
if cli_arg.is_single_thread() {
// 单线程运行的时候也是让他放在主线程跑
let mut config = cli_arg.as_cacl_config();
config.core_affinity = Some(1 << cli_arg.pick_core);
set_process_cores(config.core_affinity.unwrap());
cacluate::cacl(config, 1, &out_path);
} else {
for i in 0..cli_arg.thread_count {
n += 1;
let mut config = cli_arg.as_cacl_config();
// 核心亲和性: n, n+1
config.core_affinity = Some(1 << i);
cores |= 1 << i;
let out_path = out_path.clone();
let thread_name = format!("thread_{}", n);
threads.push(std::thread::spawn(move || {
info!("线程 {} 开始计算", thread_name);
cacluate::cacl(config, n, &out_path);
info!("线程 {} 结束计算", thread_name);
}));
}
set_process_cores(cores);
let mut threads = vec![];
for i in 0..cli_arg.thread_count {
n += 1;
let mut config = cli_arg.as_cacl_config(&out_path);
// 核心亲和性: n
config.core_affinity = Some(1 << i);
cores |= 1 << i;
let thread_name = format!("thread_{}", n);
threads.push(std::thread::spawn(move || {
info!("线程 {} 开始计算", thread_name);
cacl(config, n);
info!("线程 {} 结束计算", thread_name);
}));
}
crate::set_process_cores(cores);
for t in threads {
t.join().unwrap();
}
}
for t in threads {
t.join().unwrap();
}
}
#[inline(always)]
pub fn cacl(config: CacluateConfig, id: u64, outfile: &PathBuf) {
pub fn cacl(config: CacluateConfig, id: u64) {
// 初始猜测的时间间隔
let mut report_interval = 100000; // 第一次猜测测 10w 次, 获取初始数据
let mut run_speed = 0.0;
@ -92,7 +83,7 @@ pub fn cacl(config: CacluateConfig, id: u64, outfile: &PathBuf) {
let mut get_count: u32 = 0;
// 设置线程亲和性
if let Some(core_affinity) = config.core_affinity {
crate::set_thread2core(core_affinity)
crate::set_thread2core(1 << core_affinity)
}
// 提前准备好 team_namer
@ -121,9 +112,10 @@ pub fn cacl(config: CacluateConfig, id: u64, outfile: &PathBuf) {
d_t.as_secs_f64(),
// 根据对比上一段运行速度 输出 emoji
// ⬆️ ➡️ ⬇️
if new_run_speed > run_speed {
// 两个值 相差 0.1 之内都是 ➡️
if new_run_speed > run_speed + 0.1 {
"⬆️".green()
} else if new_run_speed < run_speed {
} else if new_run_speed < run_speed - 0.1 {
// 橙色
"⬇️".red()
} else {
@ -161,11 +153,11 @@ pub fn cacl(config: CacluateConfig, id: u64, outfile: &PathBuf) {
get_count += 1;
info!("Id:{:>15}|{}|{:.4}|{:.4}|{}", i, full_name, xu, xu_qd, main_namer.get_info());
// 写入文件
let write_in = format!(
// <full_name>,<id>,<xu>,<xuqd>,<main_namer.get_info()>
"{},{:>15},{:.4},{:.4},{}\n",
full_name,
main_namer.get_fullname(),
i,
xu,
xu_qd,
@ -176,12 +168,12 @@ pub fn cacl(config: CacluateConfig, id: u64, outfile: &PathBuf) {
match std::fs::OpenOptions::new()
.append(true)
.create(true)
.open(outfile)
.open(&config.out_file)
.and_then(|mut file| file.write(write_in.as_bytes()))
{
Ok(_) => {}
Err(e) => {
warn!("写入文件<{:?}>失败: {}", outfile, e);
warn!("写入文件<{:?}>失败: {}", config.out_file, e);
}
}
}

View File

@ -36,16 +36,16 @@ pub struct Command {
/// 预期状态输出时间间隔 (秒)
#[arg(long, short = 'r', default_value_t = 10)]
pub report_interval: u64,
/// Windows 下会强制单线程, 且设置线程亲和性为核心 0
#[arg(long = "bench", default_value_t = false)]
pub bench: bool,
/// 单线程模式 / benchmark 模式下的核心亲和性核心号 (从 0 开始)
#[arg(long = "core-pick", default_value_t = 0)]
pub pick_core: usize,
/// 一个 batch 多大 单线程下无效
#[arg(long, short = 'b', default_value_t = 100000)]
pub batch_size: u64,
/// 单线程模式模式下的核心亲和性核心号 (从 0 开始)
#[arg(long = "core-pick")]
pub pick_core: Option<usize>,
}
impl Command {
pub fn as_cacl_config(&self) -> CacluateConfig {
pub fn as_cacl_config(&self, path: &PathBuf) -> CacluateConfig {
CacluateConfig {
start: self.start,
end: self.end,
@ -54,13 +54,12 @@ impl Command {
qp_expect: self.qp_expect,
team: self.team.clone(),
report_interval: self.report_interval,
core_affinity: if self.bench { Some(1 << self.pick_core) } else { None },
core_affinity: self.pick_core.map(|x| 1 << x),
out_file: path.clone(),
}
}
pub fn is_single_thread(&self) -> bool {
self.thread_count == 1
}
pub fn is_single_thread(&self) -> bool { self.thread_count == 1 }
}
pub fn set_thread2core(core: usize) {
@ -106,7 +105,6 @@ fn main() {
let left = cli_arg.start % cli_arg.thread_count as u64;
cli_arg.end = cli_arg.end.wrapping_add(left);
let mut threads = vec![];
let now = chrono::Local::now().format("%Y-%m-%d_%H-%M-%S").to_string();
// namerena-<team>-<time>.csv
// <time>: %Y-%m-%d-%H-%M-%S
@ -119,14 +117,12 @@ fn main() {
return;
}
info!("开始: {} 结尾: {}", cli_arg.start, cli_arg.end);
info!("线程数: {}", cli_arg.thread_count);
info!("八围预期: {}", cli_arg.prop_expect);
info!("队伍名: {}", cli_arg.team);
info!("输出文件名: {:?}", out_path);
info!("预期状态输出时间间隔: {} 秒", cli_arg.report_interval);
info!("是否启动 benchmark 模式: {}", cli_arg.bench);
// info!("开始: {} 结尾: {}", cli_arg.start, cli_arg.end);
// info!("线程数: {}", cli_arg.thread_count);
// info!("八围预期: {}", cli_arg.prop_expect);
// info!("队伍名: {}", cli_arg.team);
// info!("输出文件名: {:?}", out_path);
// info!("预期状态输出时间间隔: {} 秒", cli_arg.report_interval);
cacluate::start_main(cli_arg, out_path);
}

View File

@ -678,11 +678,7 @@ impl Namer {
}
pub fn get_fullname(&self) -> String {
if self.team.is_empty() {
self.name.clone()
} else {
format!("{}@{}", self.name, self.team)
}
format!("{}@{}", self.name, if self.team.is_empty() { &self.name } else { &self.team })
}
}