В прошлом посте вы видели ужас ручных интринсиков. Представьте, что вам нужно поддерживать SSE2, AVX2, AVX-512, да еще и ARM NEON для макбуков. Это ад из
cfg_if и дублирования кода.Rust сообщество решает эту проблему. Встречайте Portable SIMD (сейчас это крейт
portable-simd или фича #![feature(portable_simd)] в nightly).Идея: мы используем абстрактные типы "широких" чисел, а компилятор сам мапит их на лучшие инструкции целевой платформы.
Выглядит это потрясающе чисто:
#![feature(portable_simd)] // Нужен nightly Rust
use std::simd::{f32x8, Simd};
fn add_portable(a: &[f32], b: &[f32], out: &mut [f32]) {
// Берем чанки по 8 элементов
let chunks_a = a.chunks_exact(8);
let chunks_b = b.chunks_exact(8);
let chunks_out = out.chunks_exact_mut(8);
for ((slice_a, slice_b), slice_out) in chunks_a.zip(chunks_b).zip(chunks_out) {
// Превращаем слайсы в SIMD-вектора (почти бесплатно)
let vec_a = f32x8::from_slice(slice_a);
let vec_b = f32x8::from_slice(slice_b);
// Обычный оператор "+" работает как SIMD сложение!
let vec_res = vec_a + vec_b;
// Записываем обратно
vec_res.copy_to_slice(slice_out);
}
// + нужно обработать "хвост", если длина не кратна 8
}
Никакого
unsafe! Никаких _mm256_ugly_names!Если вы компилируете это под AVX2 - будет AVX2. Под ARM NEON - будет NEON.
Это будущее высокопроизводительного Rust. Ждем стабилизации.
#rust #simd #nightly #future
👉 @rust_lib