gpt4 book ai didi

arrays - 这是从 SIMD 数组转换为常规数字类型的未定义行为吗?

转载 作者:行者123 更新时间:2023-11-29 07:54:34 26 4
gpt4 key购买 nike

我有一个浮点值数组,我需要执行一些易于向量化的操作,例如对所有这些值求和,然后将它们全部除以该总和。我还需要访问(主要是读取)数组的各个元素。我想我可以使用 SIMD 类型来启用数组的矢量化。每当我需要对数组的各个元素做很多事情时,我会将数组转换为对常规浮点值数组的引用,然后访问该引用,如下所示:

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]);
}

这编译并且似乎工作得很好。但我担心这是未定义的行为,因为 I read那:

Transmuting between non-repr(C) types is UB

我认为 SIMD 类型(如 simd::x86::avx::f32x8)是 repr(simd) 而我不认为 [f32 ; 800] 也是 repr(C)

我知道我可以在 SIMD 类型上使用 extract 方法来获取那些单独的浮点值,但是使用上述转换为常规数组的方案会使代码更简单。

最佳答案

this Pre-RFC 中的早期定义指出

It is illegal to take an internal reference to the fields of a repr(simd) type, because the representation of booleans may require to change, so that booleans are bit-packed. The official external library providing SIMD support will have private fields so this will not be generally observable.

这显然会禁止将 simd 类型转换为数组。

实际的 RFC changed那个,所以显然你可以引用内部的东西。 RFC 还声明布局和对齐方式取决于平台。

由于我所知道的所有平台都不会向 f32x8 这样的普通 simd 类型添加填充,因此您可以假设 f32x8 的布局是“相同的”作为 [f32; 8] 就它而言,它包含 8 个 f32,它们紧密地封装在一个 32 字节的内存块中。不过顺序可能是任意的。


"Transmuting between non-repr(C) types is UB" I think simd types (like simd::x86::avx::f32x8) are repr(simd) and I don't think [f32; 800] is repr(C) either.

从技术上讲,您既不是转换 repr(simd) 类型,也不是 [f32; 800],您正在将一个引用转换为另一个引用,但结果是一样的。


正如@Chris Emerson 所指出的,您示例中的不安全性来自生命周期链的中断。要恢复它,请创建一个抽象边界:

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

关于arrays - 这是从 SIMD 数组转换为常规数字类型的未定义行为吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39014338/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com