我正在开发一个应用程序,它将-1.0到1.0范围内的Float样本转换为带符号的16位,以确保优化(SSE)例程的输出是准确的我已经编写了一组运行非针对SSE版本的优化版本并比较它们的输出。
在开始之前,我已确认SSE舍入模式设置为最接近。
在我的测试用例中,公式为:
ratio = 65536 / 2
output = round(input * ratio)
在大多数情况下,结果是准确的,但在一个特定的输入上,我看到输入-0.8499908447265625
失败。
-0.8499908447265625 * (65536 / 2) = -27852.5
正常代码正确地将其舍入为-27853
,但SSE代码将其舍入为-27852
。
以下是正在使用的SSE代码:
void Float_S16(const float *in, int16_t *out, const unsigned int samples)
{
static float ratio = 65536.0f / 2.0f;
static __m128 mul = _mm_set_ps1(ratio);
for(unsigned int i = 0; i < samples; i += 4, in += 4, out += 4)
{
__m128 xin;
__m128i con;
xin = _mm_load_ps(in);
xin = _mm_mul_ps(xin, mul);
con = _mm_cvtps_epi32(xin);
out[0] = _mm_extract_epi16(con, 0);
out[1] = _mm_extract_epi16(con, 2);
out[2] = _mm_extract_epi16(con, 4);
out[3] = _mm_extract_epi16(con, 6);
}
}
根据要求提供自包含示例:
/* standard math */
float ratio = 65536.0f / 2.0f;
float in [4] = {-1.0, -0.8499908447265625, 0.0, 1.0};
int16_t out[4];
for(int i = 0; i < 4; ++i)
out[i] = round(in[i] * ratio);
/* sse math */
static __m128 mul = _mm_set_ps1(ratio);
__m128 xin;
__m128i con;
xin = _mm_load_ps(in);
xin = _mm_mul_ps(xin, mul);
con = _mm_cvtps_epi32(xin);
int16_t outSSE[4];
outSSE[0] = _mm_extract_epi16(con, 0);
outSSE[1] = _mm_extract_epi16(con, 2);
outSSE[2] = _mm_extract_epi16(con, 4);
outSSE[3] = _mm_extract_epi16(con, 6);
printf("Standard = %d, SSE = %d\n", out[1], outSSE[1]);
答案 0 :(得分:13)
尽管SSE舍入模式默认为“舍入到最接近”,但这并不是我们在学校学到的旧的熟悉的舍入方法,而是一种稍微更现代的变体,称为rint()(也称为无偏舍入,收敛舍入) ,统计学家的舍入,荷兰舍入,高斯舍入或奇偶舍入),舍入到最接近的偶数整数值。从统计角度来看,这种舍入方法应该比更传统的方法更好。您会看到与default rounding mode for IEEE-754等功能相同的行为,它也是round()。
另请注意,虽然标准库函数ROUNDPS
(_mm_round_ps
)使用传统的舍入方法,但SSE指令http://errors.angularjs.org/1.4.4/ng/areq?p0=DatepickerDemoCtrl&p1=not%20a%20function%2C%20got%20undefined使用银行家的舍入。
答案 1 :(得分:7)
这是所有浮点处理的默认行为,而不仅仅是SSE。 Round half to even or banker's rounding是根据IEEE 754标准的默认舍入模式。
使用它的原因是始终向上舍入(或向下)会导致半点错误,即使在适度数量的操作中应用也会累积。半分可能导致一些非常重要的错误 - 足够重要,它们成为超人3中的情节点。
将一半减半到偶数或奇数,导致负半点和正半点误差在应用于许多操作时相互消除。
这在SSE操作中也是可取的。 SSE操作通常用于信号处理(音频,图像),工程和统计场景,其中一致的舍入误差将表现为噪声并且需要额外的处理来移除(如果可能的话)。银行家的舍入确保消除噪音