CPUID
- Rust kursu
- Uzman
- Ders 29/46
- 4 dk
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.)
Başlangıç kodu
fn main() {
// buraya yaz
}Örnek çözüm
#[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);
}Beklenen çıktı
true true
Soru ve cevaplar
Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.
1 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 Doğru cevap
- cpuid yoktur
Açıklama: std::arch::__cpuid bu ayrıntıyı doğru ele alır; çoğu durumda intrinsics, ham assembly'den daha güvenlidir.
2 Özellik denetimi
if ____!("avx2") {
// AVX2'li yol
}
if is_x86_feature_detected!("avx2") {
// AVX2'li yol
}
Açıklama: is_x86_feature_detected! işlemcinin özelliği desteklediğini çalışma anında denetler.
3 Araç ve zamanı
| Kavram | Anlamı |
|---|---|
#[cfg(target_feature)] |
Derleme anı |
is_x86_feature_detected! |
Çalışma anı |
__cpuid(0) |
Üretici bilgisi |
#[target_feature(enable)] |
Fonksiyon başına özellik |