CodeBlanks Logo Icon CodeBlanks

Mask

Mask ile şartlı paket işlemleri yaparsın.

Mask

SIMD'de karşılaştırmalar tek bir bool değil, şerit başına bir bool içeren bir maske üretir. Maskeler dallanma yerine select ile kullanılır: her şerit için ya bir vektörden ya diğerinden değer alınır. Böylece if olmadan koşullu işlem yapılır:

// nightly std::simd
let a = i32x4::from_array([1, 5, 3, 8]);
let m = a.simd_gt(i32x4::splat(4));        // [false, true, false, true]
let c = m.select(a, i32x4::splat(0));      // [0, 5, 0, 8]

Dallanmasız kod, tahmin edilemeyen koşullarda işlemcinin dal tahmin cezasından da kaçınır.

Dizilerle maske ve seçim

Aynı fikri kararlı Rust'ta dizilerle yazabiliriz; yapı derleyicinin vektörleştirebileceği dallanmasız bir biçimdir:

fn buyuk_mu(a: [i32; 4], esik: i32) -> [bool; 4] {
    a.map(|x| x > esik)
}

fn sec(m: [bool; 4], a: [i32; 4], b: [i32; 4]) -> [i32; 4] {
    std::array::from_fn(|i| if m[i] { a[i] } else { b[i] })
}

[T; N]::map, her elemana closure uygulayıp yeni bir dizi döndürür.

Uygulama Maske ve seçim

Yukarıdaki buyuk_mu ve sec fonksiyonlarını yaz. a = [1, 5, 3, 8] ve eşik 4 için maskeyi ve sec(m, a, [0; 4]) sonucunu {:?} ile boşlukla yazdır.

Başlangıç kodu

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

Örnek çözüm

main.rs
fn buyuk_mu(a: [i32; 4], esik: i32) -> [bool; 4] {
    a.map(|x| x > esik)
}

fn sec(m: [bool; 4], a: [i32; 4], b: [i32; 4]) -> [i32; 4] {
    std::array::from_fn(|i| if m[i] { a[i] } else { b[i] })
}

fn main() {
    let a = [1, 5, 3, 8];
    let m = buyuk_mu(a, 4);
    println!("{:?} {:?}", m, sec(m, a, [0; 4]));
}

Beklenen çıktı

[false, true, false, true] [0, 5, 0, 8]

Soru ve cevaplar

Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.

1 Neden SIMD'de <code>if</code> yerine maske kullanılır?

  • Gelenek
  • Maske gereksizdir
  • Şeritler aynı talimatı birlikte çalıştırır; şerit başına ayrı dallanma yoktur Doğru cevap
  • if yavaş derlenir

Açıklama: İki dalın sonucu da hesaplanır ve maske hangisinin tutulacağını seçer.

2 Dizi map

Soru
fn buyuk_mu(a: [i32; 4], esik: i32) -> [bool; 4] {
    a.____(|x| x > esik)
}
Cevap
fn buyuk_mu(a: [i32; 4], esik: i32) -> [bool; 4] {
    a.map(|x| x > esik)
}

Açıklama: Dizi üzerinde map aynı boyutlu yeni bir dizi döndürür.

3 İşlem ve sonuç (a = [1, 5, 3, 8])

Kavram Anlamı
a > 4 [false, true, false, true]
sec(m, a, [0; 4]) [0, 5, 0, 8]
a > 0 [true, true, true, true]
a > 10 [false, false, false, false]

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