在this OpenCL reference sheet(断开链接)的第3页,有两个内置向量长度函数,参数相同:length()
和half_length()
。
这些功能之间有什么区别?我从名称中选择一个比另一个更“快”但在什么情况下?对于这种速度增加,它是否具有准确性?如果没有,为什么会使用length()
而不是fast_length()
?
答案 0 :(得分:7)
根据OpenCL规范(版本1.1,第215页):
float length(floatn p)
:返回向量p
的长度,即sqrt(p.x²+p.y²+...)
float fast_length(floatn p)
:返回计算为p
half_sqrt(p.x²+p.y²+...)
的长度
所以fast_length
使用half_sqrt
,而length
使用sqrt
。您可以猜测sqrt
可以更好地保证准确性,但可能会更慢。更重要的是:
sqrt
的最小准确度:3ulp(精度最低的单位) half_sqrt
的最低准确度:8192ulp
因此,half_sqrt
可能比sqrt
精确约11位(实际上它可能精确到13位,因为sqrt
不要求更好,然后严格必要)。由于float
的尾数为23bit
(加上一个隐含位)half_sqrt
,因此只承诺大约10位精度(11位包括隐式1)。但是,如果硬件具有这样的功能,它可能会更快。在硬件中,让sqrt
或rsqrt
指令仅提供少量位(如10-14)并在指令之后使用Newton-Raphson迭代来获得必要的精度并不罕见。在这种情况下使用half_sqrt
显然更快。