“奇数大小的对齐向量上的“安全” SIMD运算符?

问题描述 投票:2回答:1

比方说,我有一些16字节对齐的结构,只包装3xFloat32数组:

#[repr(C, align(16))]
pub struct Vector(pub [f32; 3]);

现在,我想将其划分为两个实例,例如:

use core::arch::x86_64;

let a = Vector([1f32, 2f32, 3f32]);
let b = Vector([4f32, 5f32, 6f32]);
let mut sum = Vector([0f32, 0f32, 0ff32]);

unsafe {
    let a1 = x86_64::_mm_load_ps(a.0.as_ptr());
    let b1 = x86_64::_mm_load_ps(b.0.as_ptr());
    let sum1 = x86_64::_mm_div_ps(a1, b1);
    x86_64::_mm_store_ps(sum.0.as_mut_ptr(), sum);
}

它可以进行除法,但是存在一个问题:第4个元素包含垃圾,除其他外,这可能表示NaN。并且,如果未屏蔽某些例外标志,则将触发SIGFPE。我想以某种方式避免这种情况,而不会完全沉默信号。即我或者只想在第4对元素上使其静音,或者在其中添加一些合理的值。最好,最快的方法是什么?还是总体上有更好的方法?

rust floating-point sse simd floating-point-exceptions
1个回答
1
投票

[通常,没有人会掩盖FP异常,否则您需要改组,例如复制元素之一,因此顶部元素与其他元素之一进行相同的划分。或还有其他一些已知的安全物品。

也许,如果您可以假设该元素中的分红不是NaN,那么也许只需要对除数进行改组就可以摆脱。

使用AVX512,您可以使用零掩码抑制元素的异常,但是直到那时为止,还没有这样的功能。此外,AVX512还允许您覆盖舍入模式+不遮盖所有异常(SAE),因此您可以使最接近偶数显式获得SAE。但这会抑制all元素的异常。


严重,请勿启用FP例外。如果异常的数量是明显的副作用,编译器几乎/不知道如何以安全的方式进行优化。例如GCC的-ftrapping-math默认为打开状态,但已损坏。

我不会认为LLVM会更好;默认的严格FP可能仍会进行优化,使一个SIGFPE的源将提高2或4。也许甚至将其提高0的源也将提高1,或者反之亦然,例如GCC破损且几乎无用的默认设置。] >

但是,如果您希望永远都没有某种异常,启用FP异常对于调试可能会很有用。但是您可以通过忽略具有该源地址的SIMD指令来处理偶尔出现的误报。

© www.soinside.com 2019 - 2024. All rights reserved.