torsh_sparse/performance_tools/optimization/
hardware.rs1use crate::TorshResult;
4use std::collections::HashMap;
5use std::time::Instant;
6
7#[derive(Debug)]
9pub struct HardwareBenchmark {
10 system_info: SystemInfo,
12 benchmark_cache: HashMap<String, f64>,
14 feature_support: HashMap<String, bool>,
16}
17
18#[derive(Debug, Clone)]
20pub struct SystemInfo {
21 pub cpu_info: CpuInfo,
23 pub memory_info: MemoryInfo,
25 pub cache_info: CacheInfo,
27 pub hardware_features: Vec<String>,
29 pub os_info: String,
31}
32
33#[derive(Debug, Clone)]
35pub struct CpuInfo {
36 pub physical_cores: usize,
38 pub logical_cores: usize,
40 pub base_frequency_mhz: f64,
42 pub architecture: String,
44 pub instruction_sets: Vec<String>,
46}
47
48#[derive(Debug, Clone)]
50pub struct MemoryInfo {
51 pub total_memory: usize,
53 pub available_memory: usize,
55 pub memory_bandwidth_gbps: f64,
57}
58
59#[derive(Debug, Clone)]
61pub struct CacheInfo {
62 pub l1_cache_size: usize,
64 pub l2_cache_size: usize,
66 pub l3_cache_size: usize,
68 pub cache_line_size: usize,
70}
71
72#[derive(Debug, Clone)]
74pub struct SystemCapabilityReport {
75 pub system_info: SystemInfo,
77 pub capability_scores: HashMap<String, f64>,
79 pub recommendations: Vec<String>,
81 pub benchmark_timestamp: std::time::SystemTime,
83}
84
85impl Default for HardwareBenchmark {
86 fn default() -> Self {
87 Self::new()
88 }
89}
90
91impl HardwareBenchmark {
92 pub fn new() -> Self {
94 let system_info = SystemInfo::detect();
95 Self {
96 system_info,
97 benchmark_cache: HashMap::new(),
98 feature_support: HashMap::new(),
99 }
100 }
101
102 pub fn analyze_system_capabilities(&mut self) -> TorshResult<SystemCapabilityReport> {
104 let mut capabilities = HashMap::new();
105
106 capabilities.insert(
108 "cpu_compute_score".to_string(),
109 self.benchmark_cpu_compute()?,
110 );
111 capabilities.insert(
112 "memory_bandwidth_score".to_string(),
113 self.benchmark_memory_bandwidth()?,
114 );
115 capabilities.insert(
116 "cache_efficiency_score".to_string(),
117 self.benchmark_cache_efficiency()?,
118 );
119
120 if self.detect_simd_support() {
122 capabilities.insert(
123 "simd_acceleration_score".to_string(),
124 self.benchmark_simd_performance()?,
125 );
126 }
127
128 if self.detect_numa_support() {
129 capabilities.insert(
130 "numa_efficiency_score".to_string(),
131 self.benchmark_numa_performance()?,
132 );
133 }
134
135 let recommendations = self.generate_hardware_recommendations(&capabilities);
137
138 Ok(SystemCapabilityReport {
139 system_info: self.system_info.clone(),
140 capability_scores: capabilities,
141 recommendations,
142 benchmark_timestamp: std::time::SystemTime::now(),
143 })
144 }
145
146 pub fn benchmark_cpu_compute(&mut self) -> TorshResult<f64> {
148 let cache_key = "cpu_compute".to_string();
149 if let Some(&cached_score) = self.benchmark_cache.get(&cache_key) {
150 return Ok(cached_score);
151 }
152
153 let start = Instant::now();
154 let iterations = 1_000_000;
155
156 let mut sum = 0.0;
158 for i in 0..iterations {
159 sum += (i as f64).sqrt().sin().cos();
160 }
161
162 let duration = start.elapsed();
163 let score = (iterations as f64 / duration.as_secs_f64()) / 1_000_000.0; std::hint::black_box(sum);
167
168 self.benchmark_cache.insert(cache_key, score);
169 Ok(score)
170 }
171
172 pub fn benchmark_memory_bandwidth(&mut self) -> TorshResult<f64> {
174 let cache_key = "memory_bandwidth".to_string();
175 if let Some(&cached_score) = self.benchmark_cache.get(&cache_key) {
176 return Ok(cached_score);
177 }
178
179 let size = 10_000_000; let data: Vec<f64> = (0..size).map(|i| i as f64).collect();
181
182 let start = Instant::now();
183 let sum: f64 = data.iter().sum();
184 let duration = start.elapsed();
185
186 let bytes_processed = size * std::mem::size_of::<f64>();
187 let bandwidth_gbps =
188 (bytes_processed as f64 / duration.as_secs_f64()) / (1024.0 * 1024.0 * 1024.0);
189
190 std::hint::black_box(sum);
192
193 self.benchmark_cache.insert(cache_key, bandwidth_gbps);
194 Ok(bandwidth_gbps)
195 }
196
197 pub fn benchmark_cache_efficiency(&mut self) -> TorshResult<f64> {
199 let cache_key = "cache_efficiency".to_string();
200 if let Some(&cached_score) = self.benchmark_cache.get(&cache_key) {
201 return Ok(cached_score);
202 }
203
204 let size = 1_000_000;
205 let data: Vec<f64> = vec![1.0; size];
206
207 let start_sequential = Instant::now();
209 let mut sum_sequential = 0.0;
210 for &value in &data {
211 sum_sequential += value;
212 }
213 let sequential_time = start_sequential.elapsed();
214
215 let start_random = Instant::now();
217 let mut sum_random = 0.0;
218 for i in 0..size {
219 let index = (i * 7) % size; sum_random += data[index];
221 }
222 let random_time = start_random.elapsed();
223
224 let efficiency_score = sequential_time.as_secs_f64() / random_time.as_secs_f64();
226
227 std::hint::black_box((sum_sequential, sum_random));
229
230 self.benchmark_cache.insert(cache_key, efficiency_score);
231 Ok(efficiency_score)
232 }
233
234 fn detect_simd_support(&mut self) -> bool {
236 let feature = "simd_support".to_string();
237 if let Some(&cached) = self.feature_support.get(&feature) {
238 return cached;
239 }
240
241 let supported = cfg!(target_feature = "sse2")
243 || cfg!(target_feature = "avx")
244 || cfg!(target_feature = "neon");
245 self.feature_support.insert(feature, supported);
246 supported
247 }
248
249 fn detect_numa_support(&mut self) -> bool {
251 let feature = "numa_support".to_string();
252 if let Some(&cached) = self.feature_support.get(&feature) {
253 return cached;
254 }
255
256 let supported = self.system_info.cpu_info.physical_cores > 4;
258 self.feature_support.insert(feature, supported);
259 supported
260 }
261
262 fn benchmark_simd_performance(&mut self) -> TorshResult<f64> {
264 let cache_key = "simd_performance".to_string();
266 if let Some(&cached_score) = self.benchmark_cache.get(&cache_key) {
267 return Ok(cached_score);
268 }
269
270 let score = if self.detect_simd_support() {
271 0.8 } else {
273 0.2 };
275
276 self.benchmark_cache.insert(cache_key, score);
277 Ok(score)
278 }
279
280 fn benchmark_numa_performance(&mut self) -> TorshResult<f64> {
282 let cache_key = "numa_performance".to_string();
284 if let Some(&cached_score) = self.benchmark_cache.get(&cache_key) {
285 return Ok(cached_score);
286 }
287
288 let score = if self.detect_numa_support() {
289 0.7 } else {
291 0.9 };
293
294 self.benchmark_cache.insert(cache_key, score);
295 Ok(score)
296 }
297
298 fn generate_hardware_recommendations(
300 &self,
301 capabilities: &HashMap<String, f64>,
302 ) -> Vec<String> {
303 let mut recommendations = Vec::new();
304
305 if let Some(&cpu_score) = capabilities.get("cpu_compute_score") {
307 if cpu_score > 2.0 {
308 recommendations.push(
309 "High CPU performance detected - consider CPU-intensive algorithms".to_string(),
310 );
311 } else if cpu_score < 0.5 {
312 recommendations.push(
313 "Limited CPU performance - prefer memory-efficient algorithms".to_string(),
314 );
315 }
316 }
317
318 if let Some(&memory_score) = capabilities.get("memory_bandwidth_score") {
320 if memory_score > 10.0 {
321 recommendations.push(
322 "High memory bandwidth available - streaming algorithms recommended"
323 .to_string(),
324 );
325 } else if memory_score < 2.0 {
326 recommendations
327 .push("Limited memory bandwidth - minimize memory access patterns".to_string());
328 }
329 }
330
331 if let Some(&cache_score) = capabilities.get("cache_efficiency_score") {
333 if cache_score > 0.8 {
334 recommendations
335 .push("Excellent cache performance - leverage block algorithms".to_string());
336 } else if cache_score < 0.3 {
337 recommendations.push(
338 "Poor cache performance - consider cache-oblivious algorithms".to_string(),
339 );
340 }
341 }
342
343 if capabilities.contains_key("simd_acceleration_score") {
345 recommendations
346 .push("SIMD support detected - enable vectorized operations".to_string());
347 }
348
349 if capabilities.contains_key("numa_efficiency_score") {
351 recommendations
352 .push("NUMA system detected - consider thread affinity optimization".to_string());
353 }
354
355 recommendations
356 }
357}
358
359impl SystemInfo {
360 pub fn detect() -> Self {
362 Self {
363 cpu_info: CpuInfo::detect(),
364 memory_info: MemoryInfo::detect(),
365 cache_info: CacheInfo::detect(),
366 hardware_features: Self::detect_hardware_features(),
367 os_info: Self::detect_os_info(),
368 }
369 }
370
371 fn detect_hardware_features() -> Vec<String> {
373 #[allow(unused_mut)]
374 let mut features = Vec::new();
375
376 #[cfg(target_feature = "sse2")]
378 features.push("SSE2".to_string());
379
380 #[cfg(target_feature = "avx")]
381 features.push("AVX".to_string());
382
383 #[cfg(target_feature = "avx2")]
384 features.push("AVX2".to_string());
385
386 #[cfg(target_feature = "fma")]
387 features.push("FMA".to_string());
388
389 features
390 }
391
392 fn detect_os_info() -> String {
394 format!("{}", std::env::consts::OS)
395 }
396}
397
398impl CpuInfo {
399 pub fn detect() -> Self {
401 Self {
403 physical_cores: 4, logical_cores: 8, base_frequency_mhz: 2400.0, architecture: std::env::consts::ARCH.to_string(),
407 instruction_sets: vec!["x86_64".to_string()], }
409 }
410}
411
412impl MemoryInfo {
413 pub fn detect() -> Self {
415 Self {
417 total_memory: 16 * 1024 * 1024 * 1024, available_memory: 8 * 1024 * 1024 * 1024, memory_bandwidth_gbps: 25.6, }
421 }
422}
423
424impl CacheInfo {
425 pub fn detect() -> Self {
427 Self {
429 l1_cache_size: 32 * 1024, l2_cache_size: 256 * 1024, l3_cache_size: 8 * 1024 * 1024, cache_line_size: 64, }
434 }
435}