Пост канала
💀 Хардкорный режим: std::arch и интринсики Автовекторизация не сработала? Алгоритм слишком сложен для LLVM? Придется марать руки. Встречайте std::arch. Это модуль, дающий доступ к конкретным инструкциям процессора (интринсикам). Это очень unsafe. Это не портабельно (код для x86 не заработает на ARM M1). Как выглядит сложение массивов на AVX2 (x86_64): #[cfg(target_arch = "x86_64")] use std::arch::x86_64::*; // Атрибут важен! Он говорит компилятору, что внутри этой функции // можно использовать 256-битные регистры. #[target_feature(enable = "avx2")] unsafe fn add_avx2(a: &[f32], b: &[f32], out: &mut [f32]) { // Мы обязаны обрабатывать данные чанками по 8 штук. // (Опустим проверки длин и обработку "хвостов" для краткости) for i in (0..a.len()).step_by(8) { // Загружаем 8 float'ов в 256-битный регистр let vec_a = _mm256_loadu_ps(a.as_ptr().add(i)); let vec_b = _mm256_loadu_ps(b.as_ptr().add(i)); // ОДНА инструкция сложения для 8 пар чисел let vec_res = _mm256_add_ps(vec_a, vec_b); // Выгружаем обратно в память _mm256_storeu_ps(out.as_mut_ptr().add(i), vec_res); } } Главная опасность: Если вы вызовете эту функцию на старом процессоре (без AVX2), программа упадет с ошибкой "Illegal Instruction". Решение: Runtime detection. Вы должны проверять фичи процессора в рантайме. fn add_smart(a: &[f32], b: &[f32], out: &mut [f32]) { if is_x86_feature_detected!("avx2") { // Безопасно, мы проверили unsafe { add_avx2(a, b, out) }; } else { // Медленный фоллбэк для старого железа add_scalar(a, b, out); } } Это сложно, больно, но дает максимальный контроль над железом. #rust #simd #unsafe #lowlevel #intrinsics 👉 @channel_rust_lib
Открыть в MAX- Просмотры
- 370
- ER
- 1,4%
- Реакции
- 5