Когда я пытаюсь хранить и load 256 бит в 256-битный вектор AVX2 и обратно, я не получаю ожидаемого результата в режиме выпуска.
use std::arch::x86_64::*;
fn main() {
let key = [1u64, 2, 3, 4];
let avxreg = unsafe { _mm256_load_si256(key.as_ptr() as *const __m256i) };
let mut back_key = [0u64; 4];
unsafe { _mm256_storeu_si256(back_key.as_mut_ptr() as *mut __m256i, avxreg) };
println!("back_key: {:?}", back_key);
}
В режиме отладки:
back_key: [1, 2, 3, 4]
В режиме выпуска:
back_key: [1, 2, 0, 0]
Задняя половина либо не загружается, либо не хранится, и я не могу понять, какая именно.
Что странно, так это то, что нацелен на работу собственного процессора. В режиме выпуска + RUSTFLAGS="-C target-cpu=native"
back_key: [1, 2, 3, 4]
Я даже пытался избавиться от ошибок Clippy, безрезультатно принудительно выравнивая (я не уверен, что приведенный ниже код вообще считается более правильным).
use std::arch::x86_64::*;
#[repr(align(256))]
#[derive(Debug)]
struct Key([u64; 4]);
fn main() {
let key = Key([1u64, 2, 3, 4]);
let avxreg = unsafe { _mm256_load_si256(&key as *const _ as *const __m256i) };
let mut back_key = Key([0u64; 4]);
unsafe { _mm256_storeu_si256((&mut back_key) as *mut _ as *mut __m256i, avxreg) };
println!("back_key: {:?}", back_key);
}
- Почему это происходит?
- Есть ли исправление для этого конкретного варианта использования?
- Можно ли обобщить это исправление для пользовательского ввода (например: если бы я хотел взять байтовый фрагмент в качестве пользовательского ввода и выполнить ту же процедуру)
vmovaps
с невыровненным адресом генерирует ошибку) - person harold   schedule 21.09.2018println!("{:?}", avxreg);
позволяют сказать, чтоload
уже является проблемой, и используйте_mm256_loadu_si256
исправьте ее, но все же магазин по-прежнему выводит неверный результат - person Stargateur   schedule 21.09.2018#[target_feature(enable = "avx2")]
, который работает. Я думаю, что это отвечает на вопросы 2, 3, но я не знаю о 1. - person Nick Babcock   schedule 21.09.2018