cuda/math_function.h
的CUDA C的数学函数实现(acosf
)包含段落:
if (__float_as_int(a) < 0) {
t1 = CUDART_PI_F - t1;
}
其中a
和t1
是floats
而CUDART_PI_F
是先前设置为接近数学常数Pi的数值的float
。
我试图理解条件(if子句)正在测试什么,它的C等价物或函数/宏__float_as_int(a)
是什么。我搜索了__float_as_int()
的实现,但没有成功。似乎__float_as_int()
是NVIDIA NVCC的内置宏或功能。看看NVCC在以上段落中产生的PTX:
.reg .u32 %r<4>;
.reg .f32 %f<46>;
.reg .pred %p<4>;
// ...
mov.b32 %r1, %f1;
mov.s32 %r2, 0;
setp.lt.s32 %p2, %r1, %r2;
selp.f32 %f44, %f43, %f41, %p2;
很明显,__float_as_int()
不是float
到int
四舍五入。 (这会产生cvt.s32.f32
。)而是将float %f1
指定为b32
的位副本(%r1
)(注意:%r1
是键入u32
(unsigned int)!!)然后比较%r1
,好像它是s32
(签名int,令人困惑!!)和%r2
(谁的值是{ {1}})。
有人可以解释发生了什么,特别是解释了0
在if-clause测试为负面(__float_as_int()
)的情况下做了什么吗? ..并提供if-clause和/或<0
marco的C等价物?
答案 0 :(得分:4)
__float_as_int
将float
重新解释为int
。当int
最重要时,<0
为float
。对于float
,它也意味着符号位开启,但它并不意味着该数字是负数(例如,它可以是“负零”)。检查然后检查< 0.0
是否为int __float_as_int(float in) {
union fi { int i; float f; } conv;
conv.f = in;
return conv.i;
}
。
C函数可能如下所示:
__cuda___signbitf
在此标题的某些其他版本中使用{{1}}代替。