为什么 _mm_mulhrs_epi16() 总是进行有偏舍入到正无穷大?

2024-02-24

有谁知道为什么pmulhrsw指示或

_mm_mulhrs_epi16(x) := RoundDown((x * y + 16384) / 32768)

总是向正无穷大舍入?对我来说,这对负数有很大的偏差,因为像 -0.6, 0.6, -0.6, 0.6, ... 这样的序列平均起来不会等于 0。

这种行为是有意还是无意?如果是故意的,那有什么用呢?有没有一种简单的方法可以减少偏见?

对我来说幸运的是,我只需更改操作顺序即可获得偏差较小的结果(我的函数是带符号的几何平均值):

__m128i ChooseSign(x, sign)
{
  return _mm_sign_epi16(x, sign)
}
signsDifferent = _mm_srai_epi16(_mm_xor_si128(a, b), 15)   // (a ^ b) >> 15
sign = _mm_andnot_si128(signsDifferent, a)    // !signsDifferent & a
//result = ChooseSign(sqrt(a * b), sign) * fraction   // biased
result = ChooseSign(sqrt(a * b) * fraction, sign)

一个最严重的错误。我在 上问了同样的问题英特尔开发者论坛 https://software.intel.com/en-us/forums/topic/540117andysem 纠正了我,指出行为是四舍五入到最接近的整数。

我错误地认为这是有偏见的,因为来自MSDN的公式 https://learn.microsoft.com/en-us/previous-versions/bb513995(v=vs.120)

was (x * y + 16384) >> 15。这看起来非常相似int(x + 0.5)舍入方法,我知道这种方法对负数有偏见并且畏缩。但我没有意识到负数的右移与除法和转换为 int 不同。

另外,它与我的非 SIMD 参考实现不匹配,结果证明这是有偏差的,因为我正在计算int(sum / 9.0f),向零舍入。

在质疑硬件中实现的某些东西的行为之前,我应该有更多的怀疑,因为硬件会经过严格的审查,因为int(x + 0.5)将是一个非常昂贵的错误。

_mm_mulhrs_epi16()仍然有一些偏差,总是将 x.5 舍入到+infinity。但这对我的申请来说不是什么大问题。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 _mm_mulhrs_epi16() 总是进行有偏舍入到正无穷大? 的相关文章

  • 在 R 中对非常小的值使用舍入函数返回零

    有时我必须处理非常低的 p 值并以表格格式呈现它们 R 返回的值可以具有很长的有效数字 即小数点后的数字 现在 由于 p 值无论如何都很低 我倾向于在将它们写入 xls 或 tsv 文件之前缩短它们 只是为了使表格看起来漂亮 我在用R ve
  • 如何在颤振中使用精度对整数进行舍入

    我试图使折线图的 Y 轴间隔在颤动中动态化 这里MaxVal将获取Y轴的最大值 int interval maxVal 6 toInt int length interval toString length toInt 所以在这里我将 ma
  • 在Python中,整数除法中向零舍入的好方法是什么?

    1 2 gives 0 正如它应该 然而 1 2 gives 1 但我希望它向 0 舍入 即我希望 1 2 为 0 无论它是正数还是负数 最好的方法是什么 进行浮点除法 然后转换为 int 不需要额外的模块 Python 3 gt gt g
  • JQ:如何将被识别为字符串的值相乘?

    我正在尝试从交换网络套接字获取一些贸易信息 在我从套接字获取的 JSON 中 值 p 和 q 都用双引号括起来 当我尝试将两个值相乘时 它表示我正在尝试将两个字符串相乘 因此 我通过 tonumber 过滤器传递这些字符串 并且错误消息发生
  • 调用always_inline‘_mm_mullo_epi32’时内联失败:目标特定选项不匹配

    我正在尝试使用 cmake 编译 C 程序 该程序使用 SIMD 内在函数 当我尝试编译它时 出现两个错误 usr lib gcc x86 64 linux gnu 5 include smmintrin h 326 1 错误 调用alwa
  • C++ 错误:“_mm_sin_ps”未在此范围内声明

    我正在尝试对将函数应用于数组的不同方法进行基准测试 why is mm sin ps在我的范围内不知道但是 mm sqrt ps is 我怎样才能让它知道 并且编译没有错误 include
  • SSE,行主要与列主要性能问题

    出于个人和娱乐目的 我正在使用 SSE 4 1 编写一个 geom 库 我花了最后 12 个小时试图理解处理行主要与列主要存储矩阵时的性能问题 我知道 Dirext OpenGL 矩阵是以行主顺序存储的 因此对我来说 将矩阵按行主顺序存储会
  • 如何将日期时间四舍五入到最接近的 5 分钟?

    我需要一个Python3函数来四舍五入datetime datetime反对精确到 5 分钟 是的 这已经在之前的 SO 帖子中讨论过here https stackoverflow com questions 32723150 round
  • write.csv 精度 R

    我正在处理非常精确的数字 最大位数 我注意到write csv x 在 R 中有时会对数字进行四舍五入 有人注意到类似的事情吗 默认保存的位数是多少 正如文档中所写 在几乎所有情况下 数值量的转换都是受控制的 通过选项 scipen see
  • 使用 GCC 为 Linux 设备驱动程序编译 Intel AVX 内联

    我在 corei7 上的 ubuntu 上运行 gcc 版本 4 8 2 从谷歌搜索中找到了有关 AVX 内在函数的信息 但我不确定这组内在函数是否可以用于 Linux 设备驱动程序并进行编译 如果可以的话 这里的任何人都可以告诉我 mak
  • 如何使用 JavaScript 四舍五入到任意数量的有效数字?

    我尝试了下面的示例代码 function sigFigs n sig if n 0 return 0 var mult Math pow 10 sig Math floor Math log n lt 0 n n Math LN10 1 r
  • _mm256_fmadd_ps 比 _mm256_mul_ps + _mm256_add_ps 慢?

    我有一个图像处理算法来计算a b c d与AVX 伪代码如下 float a new float N float b new float N float c new float N float d new float N assign va
  • 将两个 32 位整数向量相乘,生成 32 位结果元素向量

    将每个 32 位条目乘以 2 的最佳方法是什么 mm256i互相注册 mm256 mul epu32不是我正在寻找的 因为它产生 64 位输出 我想要每个 32 位输入元素都有一个 32 位结果 而且 我确信两个 32 位值的乘法不会溢出
  • 将整数四舍五入到最接近的 10 倍数[重复]

    这个问题在这里已经有答案了 我想弄清楚如何对价格进行四舍五入 双向 例如 Round down 43 becomes 40 143 becomes 140 1433 becomes 1430 Round up 43 becomes 50 1
  • 什么是 __ext_vector_type__ 和 simd?

    我正在使用 Apple Metal API 以及所谓的simd图书馆 标题中有这样的代码 typedef attribute ext vector type 3 float vector float3 我很好奇它实际上做了什么以及为什么编译
  • 四舍五入到 25、50、75、100

    我不是一个数学爱好者 所以我很难想出一个将小数四舍五入到 25 50 75 和 100 的计算方法 这不会是典型的四舍五入 因为小数不会减少但只增加了 Example 如果 11 12 则舍入为 11 25 如果为 11 34 则舍入为 1
  • 使用 (float&)int 进行类型双关可以正常工作,(float const&)int 会像 (float)int 一样转换吗?

    VS2019 发布 x86 template
  • 什么是“矢量化”?

    现在好几次了 我在 matlab fortran 其他一些 中遇到这个术语 但我从来没有找到解释它是什么意思 它有什么作用 所以我在这里问 什么是矢量化 例如 循环矢量化 是什么意思 许多CPU具有 向量 或 SIMD 指令集 它们同时对两
  • MS Access 中的舍入

    VBA Access 中舍入的最佳方法是什么 我目前的方法是利用Excel方法 Excel WorksheetFunction Round 但我正在寻找一种不依赖Excel的方法 请注意 VBA Round 函数使用 Banker 舍入 将
  • 大数组上的 SSE 性能较慢

    我是 SSE 编程新手 所以我希望有人可以帮助我 我最近使用 GCC SSE 内在函数实现了一个函数来计算 32 位整数数组的总和 下面给出了我的实现代码 int ssum const int d unsigned int len stat

随机推荐