Rust
CPUID
CPUID gibi özel komutları çağırırsın.
CPUID
x86'nın cpuid talimatı işlemci hakkında bilgi verir: üretici adı, desteklenen talimat kümeleri (SSE, AVX, AVX-512...). eax'e bir "yaprak" numarası yazılır, sonuç eax, ebx, ecx, edx'e gelir. Elle assembly yerine standart kütüphane hazır araçlar sunar:
use std::arch::x86_64::__cpuid;
let r = unsafe { __cpuid(0) }; // yaprak 0: üretici
// r.ebx, r.edx, r.ecx → "GenuineIntel" ya da "AuthenticAMD"
if is_x86_feature_detected!("avx2") {
// AVX2'li yol
}
is_x86_feature_detected! sonucu önbelleğe alır; çalışma anında en uygun uygulamayı seçmek için idealdir.
Çalışma anı seçimi
Aynı işlevin farklı talimat kümeleri için birkaç sürümü yazılıp çalışma anında en iyisi seçilir:
fn toplam(v: &[f32]) -> f32 {
#[cfg(target_arch = "x86_64")]
if is_x86_feature_detected!("avx2") {
return unsafe { toplam_avx2(v) };
}
v.iter().sum()
}
#[cfg(target_arch = "x86_64")]
#[target_feature(enable = "avx2")]
unsafe fn toplam_avx2(v: &[f32]) -> f32 { v.iter().sum() }
#[target_feature] fonksiyonu, AVX2 açıkken yeniden derler; derleyici o fonksiyonda geniş vektörler kullanabilir.
Uygulama İşlemci özellikleri
x86-64'te __cpuid(0).eax > 0 (desteklenen en yüksek yaprak) ve is_x86_feature_detected!("sse2") sonuçlarını boşlukla yazdır; diğer mimarilerde true true yazdır. (SSE2 her x86-64 işlemcide vardır.)
Örnek çözümü göster
#[cfg(target_arch = "x86_64")]
fn islemci_bilgisi() -> (bool, bool) {
// SAFETY: cpuid her x86-64 işlemcide vardır.
let r = unsafe { std::arch::x86_64::__cpuid(0) };
(r.eax > 0, is_x86_feature_detected!("sse2"))
}
#[cfg(not(target_arch = "x86_64"))]
fn islemci_bilgisi() -> (bool, bool) {
(true, true)
}
fn main() {
let (a, b) = islemci_bilgisi();
println!("{} {}", a, b);
}
Kendini test et
-
Neden <code>cpuid</code>'yi elle <code>asm!</code> ile yazmak zordur?
- Çok yavaştır
- Zor değildir
- rbx yazmacını LLVM ayırdığı için operand olarak kullanılamaz; kaydedip geri yüklemek gerekir
- cpuid yoktur
Cevabı göster
rbx yazmacını LLVM ayırdığı için operand olarak kullanılamaz; kaydedip geri yüklemek gerekir — std::arch::__cpuid bu ayrıntıyı doğru ele alır; çoğu durumda intrinsics, ham assembly'den daha güvenlidir.
-
Özellik denetimi
if ____!("avx2") {
// AVX2'li yol
}
Cevabı göster
if is_x86_feature_detected!("avx2") {
// AVX2'li yol
}
-
Araç ve zamanı
- #[cfg(target_feature)]
- Derleme anı
- is_x86_feature_detected!
- Çalışma anı
- __cpuid(0)
- Üretici bilgisi
- #[target_feature(enable)]
- Fonksiyon başına özellik
Sıradaki ders: Özet - Inline assembly