Ответ 1
После более тщательного чтения документов стало ясно, что мне пришлось извлечь тело в другую функцию и заставить эту функцию скомпилировать с помощью AVX2, аннотируя ее с помощью
#[target_feature(enable = "avx2")]
Или скомпилируйте всю программу с помощью
RUSTFLAGS="-C target-feature=+avx2" cargo run --release
Первый вариант лучше, потому что он гарантирует, что инструкции SIMD, используемые в функции, будут скомпилированы надлежащим образом, только на вызывающем устройстве, чтобы проверить, что их процессор имеет эти возможности перед вызовом is_x86_feature_detected!("avx2")
. Все это задокументировано, но было бы замечательно, если бы компилятор мог предупредить: "Эй, эта функция использует инструкции AVX2, но не была аннотирована с #[target_feature(enable = "avx2")]
и программа не была скомпилирована с включенным AVX2 глобально, поэтому вызов этой функции - неопределенное поведение ". Это избавило бы меня от головной боли!
Поскольку полагаться на неопределенное поведение плохо, наша первоначальная программа на игровой площадке должна быть написана так:
use std::arch::x86_64::*;
fn main() {
unsafe { run() }
}
#[target_feature(enable = "avx2")]
unsafe fn run() {
let key = [1u64, 2, 3, 4];
let avxreg = _mm256_load_si256(key.as_ptr() as *const __m256i);
let mut back_key = [0u64; 4];
_mm256_storeu_si256(back_key.as_mut_ptr() as *mut __m256i, avxreg);
println!("back_key: {:?}", back_key);
}
Некоторые примечания:
-
main
не может быть небезопасным и, следовательно, не может быть аннотированtarget_feature
, поэтому необходимо извлечь в другую функцию - Это все еще предполагает, что процессор
x86_64
работающий с кодом, обладает возможностямиavx
, поэтому убедитесь, что вы проверили перед вызовом - Не стоит задумываться о том, почему версия отладки дает правильные результаты, так как ее запуск под релизом на моем домашнем компьютере также дает правильные результаты (под некоторыми заклинаниями). Взгляд на сборку показывает, что LLVM оптимизирован так или иначе, но это не особенно проницательно.