#[derive(Debug, Clone)]
pub struct PerformanceTuning {
pub simd_threshold: usize,
pub parallel_edge_threshold: usize,
pub parallel_feature_threshold: usize,
pub batch_size: usize,
}
impl Default for PerformanceTuning {
fn default() -> Self {
Self {
simd_threshold: 8,
parallel_edge_threshold: 100,
parallel_feature_threshold: 3,
batch_size: num_cpus::get(),
}
}
}
impl PerformanceTuning {
pub fn new() -> Self {
Self::default()
}
pub fn with_simd_threshold(mut self, threshold: usize) -> Self {
self.simd_threshold = threshold;
self
}
pub fn with_parallel_edge_threshold(mut self, threshold: usize) -> Self {
self.parallel_edge_threshold = threshold;
self
}
pub fn with_parallel_feature_threshold(mut self, threshold: usize) -> Self {
self.parallel_feature_threshold = threshold;
self
}
pub fn with_batch_size(mut self, size: usize) -> Self {
self.batch_size = size;
self
}
pub fn for_small_graphs() -> Self {
Self {
simd_threshold: 16, parallel_edge_threshold: 200,
parallel_feature_threshold: 5,
batch_size: num_cpus::get(),
}
}
pub fn for_large_graphs() -> Self {
Self {
simd_threshold: 4, parallel_edge_threshold: 50,
parallel_feature_threshold: 2,
batch_size: num_cpus::get() * 2,
}
}
pub fn for_power_efficiency() -> Self {
Self {
simd_threshold: 12,
parallel_edge_threshold: 150,
parallel_feature_threshold: 4,
batch_size: num_cpus::get().min(4), }
}
pub fn for_max_throughput() -> Self {
Self {
simd_threshold: 4,
parallel_edge_threshold: 30,
parallel_feature_threshold: 1,
batch_size: num_cpus::get() * 4, }
}
}
pub struct SystemCapabilities {
cpu_count: usize,
has_avx2: bool,
has_neon: bool,
architecture: String,
}
impl SystemCapabilities {
pub fn detect() -> Self {
let cpu_count = num_cpus::get();
let has_avx2 = {
#[cfg(target_arch = "x86_64")]
{
is_x86_feature_detected!("avx2")
}
#[cfg(not(target_arch = "x86_64"))]
{
false
}
};
let has_neon = {
#[cfg(target_arch = "aarch64")]
{
std::arch::is_aarch64_feature_detected!("neon")
}
#[cfg(not(target_arch = "aarch64"))]
{
false
}
};
let architecture = {
#[cfg(target_arch = "x86_64")]
{
"x86_64".to_string()
}
#[cfg(target_arch = "aarch64")]
{
"aarch64".to_string()
}
#[cfg(not(any(target_arch = "x86_64", target_arch = "aarch64")))]
{
std::env::consts::ARCH.to_string()
}
};
Self {
cpu_count,
has_avx2,
has_neon,
architecture,
}
}
pub fn cpu_count(&self) -> usize {
self.cpu_count
}
pub fn has_avx2(&self) -> bool {
self.has_avx2
}
pub fn has_neon(&self) -> bool {
self.has_neon
}
pub fn has_simd(&self) -> bool {
self.has_avx2 || self.has_neon
}
pub fn architecture(&self) -> &str {
&self.architecture
}
pub fn recommend_tuning(&self, typical_graph_size: usize) -> PerformanceTuning {
if typical_graph_size < 100 {
PerformanceTuning::for_small_graphs()
} else if typical_graph_size > 1000 {
PerformanceTuning::for_large_graphs()
} else {
PerformanceTuning::default()
}
}
pub fn print_info(&self) {
println!("System Capabilities:");
println!(" Architecture: {}", self.architecture);
println!(" CPU Cores: {}", self.cpu_count);
println!(" SIMD Support:");
println!(" AVX2: {}", if self.has_avx2 { "✓" } else { "✗" });
println!(" NEON: {}", if self.has_neon { "✓" } else { "✗" });
println!(" Recommended: {}", if self.cpu_count >= 8 { "High-performance mode" } else { "Balanced mode" });
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_default_tuning() {
let tuning = PerformanceTuning::default();
assert_eq!(tuning.simd_threshold, 8);
}
#[test]
fn test_custom_tuning() {
let tuning = PerformanceTuning::new()
.with_simd_threshold(16)
.with_parallel_edge_threshold(200);
assert_eq!(tuning.simd_threshold, 16);
assert_eq!(tuning.parallel_edge_threshold, 200);
}
#[test]
fn test_system_capabilities() {
let caps = SystemCapabilities::detect();
assert!(caps.cpu_count() > 0);
println!("Detected {} CPUs", caps.cpu_count());
}
}