我想编写对浮点和 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;
}
这让我想到,在执行 double 时,我不想将常量的精度降低为 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时。
这听起来可能太明显了。但由于我不知道“real(0.5)”在做什么,我不知道这是否只是编译器在这个非常特殊的情况下发挥作用。反汇编代码在 real(0.5) 和 0.5f 中看起来是相同的!
所以问题仍然存在:
real(0.5)(又名 float(0.5))到底在做什么?
float(0.5) 和 0.5f 有什么区别吗? (或双倍(0.5)和0.5)
我想这也适用于 C/C++。
最佳答案
real(0.5)(又名 float(0.5))到底在做什么?
真实(0.5)
function-style cast ,在这种情况下它降低到 static_cast
real(0.5)
static_cast<real>(0.5) //exactly the same thing
这意味着 a
与 real
变量(在本例中为 float
)相乘,这意味着无需执行提升到 double
,就像 double * float
乘法的情况一样。
float(0.5) 和 0.5f 有什么区别吗? (或双倍(0.5)和0.5)
有人可能会说,用 0.5
初始化 float
可能会在运行时发生,但这对于任何现代编译器来说都是不现实的。它应该是一个空操作,它已经是用于 OP 的了。
除此之外,使用 float(0.5f)
与仅使用 0.5f
没有任何区别,对于 double(0.5) 也是如此
和 0.5
。
关于c++ - CUDA 中的 float(0.0) 与 0.0f,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40090498/