Is this conversion from a SIMD array to regular numerical behavior types undefined?

I have an array of floating point values, and I need to do some easily portable operations, for example, take the sum of all of them and then divide them by this sum. I also need to access (basically read) the individual elements of the array. I decided that I could use the SIMD type to enable the array vector. Whenever I needed to do many things with the individual elements of an array, I would transmute the array into a reference to an array of regular floating-point values, and instead refer to this link:

extern crate simd;

use simd::x86::avx::f32x8;

fn main() {
    let values8: [f32x8; 100] = [f32x8::splat(1.1); 100];
    let values: &[f32; 800] = unsafe { std::mem::transmute(&values8) };

    println!("{}", values[333]);
}

This compiles and seems to work fine. But I am worried that this behavior is undefined, because I read that:

(C) - UB

, SIMD (, simd::x86::avx::f32x8) repr(simd), , [f32; 800] repr(C).

, extract SIMD, , .

+4
2

-RFC ,

rep (simd), , . , SIMD, , .

, , - .

RFC , , , . RFC , .

, , simd, f32x8, , f32x8 " ", [f32; 8], , 8 f32, 32- . , .


" non-repr (C) - UB" , simd (, simd:: x86:: avx:: f32x8) rep (simd), , [f32; 800] (C).

repr(simd) [f32; 800], , .


@Chris Emerson, . , :

fn simd_slice(simd: &[f32x8; 100]) -> &[f32; 800] {
    unsafe { &*(simd as *const [f32x8; 100] as *const [f32; 800]) }
}
+2

- ( ), , , .

, , ; values8, ; :

extern crate simd;

use simd::f32x4;

fn main() {
    let mut values8: [f32x4; 100] = [f32x4::splat(1.1); 100];
    let values: &[f32; 400] = unsafe { std::mem::transmute(&values8) };

    let t = &mut values8[4];
    println!("{}", values[333]); // but there a mutable reference!
}
+1

Source: https://habr.com/ru/post/1651651/


All Articles