将“__m256 with random-bits”转换为 [0, 1] 范围的浮点值

Posted

技术标签:

【中文标题】将“__m256 with random-bits”转换为 [0, 1] 范围的浮点值【英文标题】:Convert "__m256 with random-bits" into float values of [0, 1] range 【发布时间】:2020-12-31 08:20:34 【问题描述】:

我有一个包含随机位的 __m256 值。

我想“解释”它,以获得另一个拥有 float__m256 统一 [0.0f, 1.0f] 范围内的值。

计划使用:

__m256 randomBits = /* generated random bits, uniformly distribution */;
__m256 invFloatRange =  _mm256_set1_ps( numeric_limits<float>::min() ); //min is a smallest increment of float precision

__m256 float01 =  _mm256_mul(randomBits, invFloatRange);
//float01 is now ready to be used

问题 1:

但是,在极少数情况下,randomBits 的所有位都为 1,因此是 NAN,这会导致问题吗?

我能做些什么来保护自己免受这种伤害?

我希望float01 始终是可用的号码

问题 2:

使用上述方法获得 [0 到 1] 范围后会保持一致吗?我知道浮点数在不同幅度下具有不同的精度

【问题讨论】:

randomBits 视为unit32,然后除以uint32 max(确保先转换为float)?即使没有 nan 和 infinity 的问题,浮点数中的随机位也不会给出均匀分布 @AlanBirtles 能否请您说明如何使用_mm256 指令来完成? uint32 的范围(与浮点数不同)与我所看到的不同。也许我们应该使用 int32 并屏蔽掉减号?这也应该消除发生 NaN 的任何可能性 实际上,按pow(2,-31) 缩放(这会在[-1, +1) 中获取数字)然后屏蔽符号位可能会更好一些。您只会丢失 1 位生成的数字,而不是 8 位。 uint32 到浮点数的转换见here。 @Kari 你看到了吗? ***.com/q/54869672/126995 【参考方案1】:

将 int32_t 重新解释为浮点数,可以

 auto const one = _mm256_set1_epi32(0x7f800000);
 a = _mm256_and_si256(a, _mm256_set1_epi32(0x007fffff));
 a = _mm256_or_si256(a, one);
 return _mm256_sub_ps(_mm256_castsi256_ps(a), _mm256_castsi256_ps(one));

and/or 序列将重用输入序列的 23 个 LSB,以在 1.0f

【讨论】:

这将永远不会生成小于 1 epsilon 的浮点数。如果您以某种方式使用了 31 位或 32 位随机性(例如,使用 uint 或 int->float 转换,然后乘以 2^-31),您将四舍五入到最接近的倍数,例如32 对于大浮点数,但每个小的随机整数仍然可以映射到不同的小浮点数,因此您有超过 2^24 个可能的结果,但仍然我认为均匀分布。 嗯,也不确定这个想法是否完美。 mumble.net/~campbell/2014/04/28/uniform-random-float【参考方案2】:

正如@Soonts 所指出的,可以在 [0, 1] 范围内统一创建浮点数:

https://***.com/a/54873925/9007125

我最终使用了以下答案:

https://***.com/a/54893167/9007125

//converts __m256i values into __m256 values, that contains floats in [0,1] range.
//https://***.com/a/54893167/9007125
inline void int_rand_int_toFloat01( const __m256i* m256i_vals,  
                                          __m256* m256f_vals) //<-- stores here.
    const static __m256 c =  _mm256_set1_ps(0x1.0p-24f); // or (1.0f / (uint32_t(1) << 24));

    __m256i* rnd =   ((__m256i*)m256i_vals);
    __m256* output =  ((__m256*)m256f_vals);

    // remember that '_mm256_cvtepi32_ps' will convert 32-bit ints into a 32-bit floats
    __m256 converted =  _mm256_cvtepi32_ps(_mm256_srli_epi32(*rnd, 8));
             *output =  _mm256_mul_ps( converted, c);

【讨论】:

你不需要指针转换你的函数参数;它们已经具有您分配的相同类型。如果您确实想将一种矢量类型重新解释为另一种,请使用_mm256_castps_si256 或其他任何东西。 (尽管指针转换对此是安全的,但仅适用于像 __m256i 这样的内在类型,而不是 int,因为内在类型就像 char* 并且可以合法地为任何东西加上别名,而不管严格的别名规则如何 - 在 GCC 中它们是用__attribute__((may_alias))定义。

以上是关于将“__m256 with random-bits”转换为 [0, 1] 范围的浮点值的主要内容,如果未能解决你的问题,请参考以下文章

将自己的博客园,打造成个人知乎

如何将thinkcmf导入eclipse

如何将Ios文件上传到

Javascript 将正则表达式 \\n 替换为 \n,将 \\t 替换为 \t,将 \\r 替换为 \r 等等

如何将视频文件转换格式

sh 一个将生成CA的脚本,将CA导入到钥匙串中,然后它将创建一个证书并与CA签名,然后将其导入到