NAN的Vectorize测试

问题描述

基于条件掩码选择一个小于或大于例如的值非常容易:

select *
from mytable
where enrollmentmonth = date '2020-07-01'
order by least(enddate,date '2020-07-31') - greatest(startdate,'2020-07-01')
fetch first row with ties

对于小于0.0f的矢量分量,以上内容将返回select * from ( select t.*,rank() over( partition by enrollmentmonth order by least(enddate,last_day(enrollmentmonth)) - greatest(startdate,trunc(enrollmentmonth,'month')) ) rn from mytable t ) t where rn = 1 ,如果矢量分量大于1.0f,则返回using vec4_t __attribute__((vector_size(4*sizeof(float)))) = float; inline auto chooseValIfInRange(vec4_t val,vec4_t if_too_small,vec4_t if_too_large) { return val < vec4_t{0.0f,0.0f,0.0f}? val_small : (val > vec4_t{1.0f,1.0f,1.0f}? val_large : val); } ,如果矢量分量在0.0f和1.0f(含)之间,则返回val。是否可以为nan选择第三个值而没有任何分支?如果可以,怎么办?

解决方法

您可以利用以下事实:只有val=NaNval>=0都为val<=1都是错误的:

using vec4_t __attribute__((vector_size(4*sizeof(float)))) = float;
    
auto chooseValIfInRange(vec4_t val,vec4_t val_small,vec4_t val_large,vec4_t val_nan)
{
    return val >=  0.0f
        ? ( val <= 1.0f ? val       : val_large)
        : ( val <= 1.0f ? val_small : val_nan  )
    ;
}

启用优化后,val <= 1.0f比较将仅执行一次:https://godbolt.org/z/Pcjezq

,

仅当f为NaN时才使用f != f

(未经测试的代码)

inline auto chooseValIfInRange(vec4_t val,vec4_t if_too_small,vec4_t if_too_large)
{
    return val < vec4_t{0.0f,0.0f,0.0f}?
        val_small
        : (val > vec4_t{1.0f,1.0f,1.0f}?
            val_large 
        : ((val != val) ? val_nan : val));
}

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...