Ver código fonte

minerd: CPU threads setup

x 7 meses atrás
pai
commit
7d11b56fdb

+ 99 - 0
bin/minerd/src/cpu.rs

@@ -0,0 +1,99 @@
+/* This file is part of DarkFi (https://dark.fi)
+ *
+ * Copyright (C) 2020-2025 Dyne.org foundation
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub struct CpuThread {
+    affinity: i32,
+    intensity: u32,
+}
+
+impl CpuThread {
+    pub fn new(affinity: i32, intensity: Option<u32>) -> Self {
+        Self { affinity, intensity: intensity.unwrap_or(0) }
+    }
+
+    pub fn is_valid(&self) -> bool {
+        self.intensity <= 8
+    }
+
+    pub fn affinity(&self) -> i32 {
+        self.affinity
+    }
+
+    pub fn intensity(&self) -> u32 {
+        if self.intensity == 0 {
+            1
+        } else {
+            self.intensity
+        }
+    }
+}
+
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct CpuThreads {
+    affinity: i32,
+    data: Vec<CpuThread>,
+}
+
+impl CpuThreads {
+    pub fn new(count: usize, intensity: u32) -> Self {
+        let mut self_ = Self { affinity: -1, data: Vec::with_capacity(count) };
+
+        for _ in 0..count {
+            self_.add(CpuThread::new(-1, Some(intensity)));
+        }
+
+        self_
+    }
+
+    pub fn is_empty(&self) -> bool {
+        self.data.is_empty()
+    }
+
+    pub fn add(&mut self, thread: CpuThread) {
+        self.data.push(thread)
+    }
+
+    pub fn threads(&self) -> &[CpuThread] {
+        &self.data
+    }
+}
+
+#[inline]
+pub fn get_affinity(index: u64, affinity: i32) -> i32 {
+    if affinity < 0 {
+        return -1
+    }
+
+    let affinity = affinity as u64;
+    let mut idx = 0u64;
+
+    for i in 0..64 {
+        if (affinity & (1u64 << i)) == 0 {
+            continue
+        }
+
+        if idx == index {
+            return i
+        }
+
+        idx += 1;
+    }
+
+    -1
+}

+ 0 - 7
bin/minerd/src/hw/cpuid.rs

@@ -74,25 +74,18 @@ impl fmt::Display for AmdZenGeneration {
 pub struct CpuInfo {
 pub struct CpuInfo {
     /// CPU vendor
     /// CPU vendor
     pub vendor: Vendor,
     pub vendor: Vendor,
-
     /// Vendor string (e.g., "GenuineIntel", "AuthenticAMD")
     /// Vendor string (e.g., "GenuineIntel", "AuthenticAMD")
     pub vendor_string: String,
     pub vendor_string: String,
-
     /// CPU family (after extended family calculation)
     /// CPU family (after extended family calculation)
     pub family: u32,
     pub family: u32,
-
     /// CPU model (after extended model calculation)
     /// CPU model (after extended model calculation)
     pub model: u32,
     pub model: u32,
-
     /// CPU stepping
     /// CPU stepping
     pub stepping: u32,
     pub stepping: u32,
-
     /// Brand string (e.g., "AMD Ryzen 9 7950X")
     /// Brand string (e.g., "AMD Ryzen 9 7950X")
     pub brand_string: String,
     pub brand_string: String,
-
     /// AMD Zen generation (if AMD)
     /// AMD Zen generation (if AMD)
     pub zen_generation: Option<AmdZenGeneration>,
     pub zen_generation: Option<AmdZenGeneration>,
-
     /// CPU supports CAT L3
     /// CPU supports CAT L3
     pub has_cat_l3: bool,
     pub has_cat_l3: bool,
 }
 }

+ 12 - 14
bin/minerd/src/hw/mod.rs

@@ -20,6 +20,8 @@ use std::collections::HashSet;
 
 
 use tracing::{debug, error, info, warn};
 use tracing::{debug, error, info, warn};
 
 
+use crate::cpu::CpuThread;
+
 /// CPU detection pub mod cpuid;
 /// CPU detection pub mod cpuid;
 pub mod cpuid;
 pub mod cpuid;
 use cpuid::{CpuInfo, CpuThreads};
 use cpuid::{CpuInfo, CpuThreads};
@@ -49,7 +51,7 @@ impl RxMsr {
         Self { is_initialized: false, is_enabled: false, cache_qos: false, saved_items: vec![] }
         Self { is_initialized: false, is_enabled: false, cache_qos: false, saved_items: vec![] }
     }
     }
 
 
-    pub fn init(&mut self, cache_qos: bool, threads: usize, save: bool) -> bool {
+    pub fn init(&mut self, cache_qos: bool, threads: &[CpuThread], save: bool) -> bool {
         if self.is_initialized {
         if self.is_initialized {
             return self.is_enabled
             return self.is_enabled
         }
         }
@@ -101,7 +103,7 @@ impl RxMsr {
 
 
         let saved_items = std::mem::take(&mut self.saved_items);
         let saved_items = std::mem::take(&mut self.saved_items);
 
 
-        if !self.wrmsr(&saved_items, 0, self.cache_qos, false) {
+        if !self.wrmsr(&saved_items, &[], self.cache_qos, false) {
             error!("[msr] Failed to restore to initial state");
             error!("[msr] Failed to restore to initial state");
         }
         }
     }
     }
@@ -109,7 +111,7 @@ impl RxMsr {
     fn wrmsr(
     fn wrmsr(
         &mut self,
         &mut self,
         preset: &[MsrItem],
         preset: &[MsrItem],
-        threads: usize, // TODO: This should be a slice of threads
+        threads: &[CpuThread],
         cache_qos: bool,
         cache_qos: bool,
         save: bool,
         save: bool,
     ) -> bool {
     ) -> bool {
@@ -134,16 +136,13 @@ impl RxMsr {
         }
         }
 
 
         // Which CPU cores will have access top the full L3 cache
         // Which CPU cores will have access top the full L3 cache
-        // TODO: Check xmrig/crypto/rx/RxMsr.cpp::wsmsr()
-        //let cpu_threads = CpuThreads::detect();
-        //let units: HashSet<i32> = cpu_threads.thread_ids().into_iter().collect();
+        let mut cache_enabled: HashSet<i32> = HashSet::new();
+        let mut cache_qos_disabled = threads.is_empty();
 
 
-        let cache_enabled: HashSet<i32> = HashSet::new();
-        //let mut cache_qos_disabled = threads.is_empty();
-        let cache_qos_disabled = true;
+        if cache_qos {
+            let cpu_threads = CpuThreads::detect();
+            let units: HashSet<i32> = cpu_threads.thread_ids().into_iter().collect();
 
 
-        /*
-        if cache_qos && !cache_qos_disabled {
             for thread in threads {
             for thread in threads {
                 let affinity = thread.affinity();
                 let affinity = thread.affinity();
                 // If some thread has no affinity or wrong affinity,
                 // If some thread has no affinity or wrong affinity,
@@ -153,12 +152,11 @@ impl RxMsr {
                     warn!(
                     warn!(
                         "Cache QoS can only be enabled when all mining threads have affinity set"
                         "Cache QoS can only be enabled when all mining threads have affinity set"
                     );
                     );
+                    break
                 }
                 }
-                break
+                cache_enabled.insert(affinity);
             }
             }
-            cache_enabled.insert(affinity);
         }
         }
-        */
 
 
         // Apply MSR values to all CPUs
         // Apply MSR values to all CPUs
         msr.write_all(|cpu| {
         msr.write_all(|cpu| {

+ 3 - 0
bin/minerd/src/lib.rs

@@ -38,6 +38,9 @@ pub mod benchmark;
 /// Hardware interfaces
 /// Hardware interfaces
 pub mod hw;
 pub mod hw;
 
 
+/// CPU information
+pub mod cpu;
+
 /// darkfid JSON-RPC related methods
 /// darkfid JSON-RPC related methods
 mod rpc;
 mod rpc;
 use rpc::{polling_task, DarkfidRpcClient};
 use rpc::{polling_task, DarkfidRpcClient};

+ 7 - 1
bin/minerd/src/main.rs

@@ -34,6 +34,7 @@ use darkfi_sdk::{
 
 
 use minerd::{
 use minerd::{
     benchmark::benchmark,
     benchmark::benchmark,
+    cpu::CpuThreads,
     hw::{cpuid::CpuInfo, RxMsr},
     hw::{cpuid::CpuInfo, RxMsr},
     MinerNodeConfig, Minerd,
     MinerNodeConfig, Minerd,
 };
 };
@@ -180,7 +181,12 @@ async fn realmain(args: Args, ex: ExecutorPtr) -> Result<()> {
 
 
     if args.boost {
     if args.boost {
         let mut rxmsr = RxMsr::new();
         let mut rxmsr = RxMsr::new();
-        rxmsr.init(args.cache_qos, args.threads, true);
+        // TODO: Right now I think we just assume default "-1" threads.
+        //       It might be incorrect, and would require a bit of config
+        //       modification to ensure something that supports defining
+        //       an array of specific cpus/threads to use.
+        let threads = CpuThreads::new(args.threads, 1);
+        rxmsr.init(args.cache_qos, threads.threads(), true);
     }
     }
 
 
     // Run system hashrate benchmark if requested
     // Run system hashrate benchmark if requested