Horizontal işlemler
- Rust kursu
- Uzman
- Ders 22/46
- 4 dk
horizontal_reduce gibi yatay işlemleri kullanırsın.
Horizontal işlemler
Şerit bazlı işlemler "dikey"dir (şerit i ile şerit i). Bir vektörün kendi şeritlerini birleştiren işlemler ise "yatay"dır: reduce_sum, reduce_max, reduce_and. Yatay işlemler pahalıdır, bu yüzden döngünün sonunda bir kez yapılır:
// nightly std::simd
let v = f32x8::from_array([1., 2., 3., 4., 5., 6., 7., 8.]);
let t = v.reduce_sum(); // 36
let m = v.reduce_max(); // 8Donanım bunu genellikle "ağaç" biçiminde yapar: önce yarıları toplar, sonra çeyrekleri, en sonda tek değer kalır.
Ağaç indirgemesi
Şeritleri yarıya katlayarak toplamak, yatay indirgemenin nasıl çalıştığını gösterir:
fn yatay_toplam(v: [f32; 8]) -> f32 {
let d4: [f32; 4] = std::array::from_fn(|i| v[i] + v[i + 4]);
let d2: [f32; 2] = std::array::from_fn(|i| d4[i] + d4[i + 2]);
d2[0] + d2[1]
}Her adımda dizinin yarısı diğer yarısıyla şerit bazlı toplanır; 8 → 4 → 2 → 1.
Uygulama Yatay toplam
Yukarıdaki yatay_toplam fonksiyonunu yaz. [1.0, 2.0, ..., 8.0] için sonucu ve fold(f32::MIN, f32::max) ile bulduğun en büyük şeriti boşlukla yazdır.
Başlangıç kodu
fn main() {
// buraya yaz
}Örnek çözüm
fn yatay_toplam(v: [f32; 8]) -> f32 {
let d4: [f32; 4] = std::array::from_fn(|i| v[i] + v[i + 4]);
let d2: [f32; 2] = std::array::from_fn(|i| d4[i] + d4[i + 2]);
d2[0] + d2[1]
}
fn main() {
let v = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0];
let m = v.iter().copied().fold(f32::MIN, f32::max);
println!("{} {}", yatay_toplam(v), m);
}Beklenen çıktı
36 8
Soru ve cevaplar
Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.
1 Ağaç biçimli toplama, soldan sağa toplamayla aynı sonucu verir mi (f32)?
- Yalnızca tamsayıda farklı
- Her zaman değil; kayan nokta toplaması birleşmeli değildir, küçük farklar olabilir Doğru cevap
- Her zaman aynı
- Hiçbir zaman
Açıklama: Derleyici bu yüzden f32 toplama döngülerini kendiliğinden yeniden sıralamaz; açık izin (ya da elle çoklu birikim) gerekir.
2 Yarıya katla
let d4: [f32; 4] = std::array::from_fn(|i| v[i] + v[i + ____]);
let d4: [f32; 4] = std::array::from_fn(|i| v[i] + v[i + 4]);
Açıklama: 8 şeritli dizi, i ile i + 4 toplanarak 4 şeride iner.
3 İşlem ve yönü
| Kavram | Anlamı |
|---|---|
a + b |
Dikey |
reduce_sum |
Yatay |
reduce_max |
Yatay (en büyük) |
splat |
Yayma |