C内在效率 - 哪个更好?

时间:2016-02-28 17:52:25

标签: c performance intrinsics

我目前正在优化一个程序,我需要计算多个类型__m128的倒数平方根。最初,在矢量化之前(当数字是浮点数时),它只是ans = 1.0f / sqrt(num),但现在我有_mm_rsqrt_ps(num)。唯一的问题是,当处理更大的数据集时,这会使我的答案有所帮助。

我想知道_mm_div_ps()_mm_sqrt_ps函数的使用是否更准确(虽然我希望花更多时间),并且在旁注中,如何指定1.0f输入__m128

感谢。

1 个答案:

答案 0 :(得分:3)

  

我想知道是否使用_mm_div_ps()和_mm_sqrt_ps函数会更准确

当然,因为rsqrtps不是一个精确的操作,所以它的全部意义在于它是一个近似值。正如您可以阅读内在指南中的手册,

  

此近似值的相对误差为:

     

|相对错误| ≤1.5* 2 -12

你可能会想要将其视为“大概有意义的位的前半部分是正确的”,但它比这更令人讨厌,它喜欢在看起来微不足道的情况下给出不精确的结果。例如,如果你输入4,你可能会得到0.499878(现在我的电脑上的实际结果)。

这并不一定意味着你需要一个完整的平方根和除法。也许你这样做,但通常将rsqrtps与精炼步骤(未经测试)结合使用就足够了:

__m128 y = _mm_rsqrt_ps(num);
__m128 yy = _mm_mul_ps(y, y);
__m128 hnum = _mm_mul_ps(num, _mm_set1_ps(0.5f));
__m128 threehalves = _mm_set1_ps(1.5f);
__m128 res = _mm_mul_ps(y, _mm_sub_ps(threehalves, _mm_mul_ps(yy, hnum)));

这精确到大约两倍于之前的位数。上面的技巧不一定是一个很大的胜利(取决于代码的使用方式),在Core2 45nm上,分区特别是平方根速度非常慢,但是从IB和更新的它几乎与延迟相关。即使在Skylake上,使用sqrt和div仍然会损失吞吐量。

上面的代码还展示了如何在向量中获取常量。