acosf实现中的CUDA __float_as_int

时间:2012-12-10 13:21:14

标签: c math cuda ptx

cuda/math_function.h的CUDA C的数学函数实现(acosf)包含段落:

if (__float_as_int(a) < 0) {
  t1 = CUDART_PI_F - t1;
}

其中at1floatsCUDART_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()不是floatint四舍五入。 (这会产生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等价物?

1 个答案:

答案 0 :(得分:4)

__float_as_intfloat重新解释为int。当int最重要时,<0float。对于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}}代替。