CUDA

时间:2016-10-17 15:39:11

标签: c++ cuda floating-point double precision

我想编写对float和double精度都有效的代码。 我正在做这样的事情:

typedef real float;
//typedef real double;

__global__ void foo(real a, real *b){
  b[0] = real(0.5)*a;
}

int main(){
  real a = 1.0f;
  real *b;
  cudaMalloc(&f, sizeof(real));
  foo<<<1,1>>>(a,b);
  return 0;
}

这让我思考,我不想在执行双精度时将常量中的精度松散为0.5f,但我不希望在进行单精度时将0.5提升到双倍!

所以我最终使用了运算符real(),如示例所示。 在单精度模式下,如果我使用real(0.5)反汇编函数'foo',我认为没有促销加倍,而只使用0.5,促销发生。

您可以使用以下方式查看:

$nvcc test.cu -arch=sm_52 -lineinfo --source-in-ptx -g -G -O0 ; cuobjdump -sass  a.out | grep "foo" -A 35

我看到了

/*0078*/                   FMUL R0, R0, 0.5;               /* 0x3868004000070000 */

使用real(0.5)或0.5f时 和

/*0078*/                   F2F.F64.F32 R4, R0;           /* 0x5ca8000000070b04 */
/*0088*/                   DMUL R4, R4, 0.5;               /* 0x3880004000070404 */
/*0090*/                   F2F.F32.F64 R0, R4;           /* 0x5ca8000000470e00 */

仅写0.5时。

这可能听起来太明显了。但由于我不知道什么是“真实(0.5)”,我不知道这是否只是编译器在这个非常特殊的情况下播放。反汇编代码在real(0.5)和0.5f中都是相同的!

所以问题仍然存在:

什么是真实的(0.5)(AKA浮点数(0.5))究竟在做什么?

float(0.5)和0.5f之间有什么区别吗? (或双倍(0.5)和0.5)

我想这也适用于C / C ++。

1 个答案:

答案 0 :(得分:4)

什么是真实的(0.5)(AKA浮点数(0.5))正在做什么?

real(0.5) function-style cast,在这种情况下,降至static_cast

real(0.5)
static_cast<real>(0.5) //exactly the same thing

这意味着areal变量相乘(在本例中为float),这意味着无需对double进行宣传,就像double * float乘法的情况。

float(0.5)和0.5f之间有什么区别吗? (或双倍(0.5)和0.5)

有人可能会说float0.5的初始化可能会在运行时发生,但这对于任何现代编译器都是不现实的。它应该是一个无操作,它已经是OP。

除此之外,使用float(0.5f)与使用0.5f没有任何区别,double(0.5)0.5也是如此。