CodeBlanks Logo Icon CodeBlanks

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.)

Başlangıç kodu

main.rs
fn main() {
    // buraya yaz
}

Örnek çözüm

main.rs
#[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

Soru
if ____!("avx2") {
    // AVX2'li yol
}
Cevap
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

Uzman bölümündeki tüm dersler