static_casting CUDA 和 C++ 之间的不一致行为
Inconsistent behavior in static_casting between CUDA and C++
我试图弄清楚为什么以下行为在 CUDA 和 C++ 之间不一致。注意x的值是完全一样的,就是static_casting好像不一致。
#include <cstdio>
template<typename RealType>
long long __host__ __device__ __forceinline__ FLOAT_TO_FIXED(RealType v) {
return (long long)(v);
}
void __global__ debug_gpu(double x) {
printf("x %.5f -x %.5f gpu %lld %lld\n", x, -x, FLOAT_TO_FIXED(-x), -FLOAT_TO_FIXED(x));
}
void debug_cpu(double x) {
printf("x %.5f -x %.5f cpu %lld %lld\n", x, -x, FLOAT_TO_FIXED(-x), -FLOAT_TO_FIXED(x));
}
int main() {
double x = static_cast<double>(131154376256114819072.0);
debug_gpu<<<1, 1>>>(x);
cudaDeviceSynchronize();
debug_cpu(x);
}
/*
x 131154376256114819072.00000 -x -131154376256114819072.00000 gpu -9223372036854775808 -9223372036854775807
x 131154376256114819072.00000 -x -131154376256114819072.00000 cpu -9223372036854775808 -9223372036854775808
*/
您似乎在取反 64 位值 -9223372036854775808,这会导致有符号整数溢出(9223372036854775808 的值不能用 64 位有符号整数表示)。这是 C 和 C++ 中的 undefined behavior。这意味着您可以获得任何结果,具体取决于编译器和执行程序的硬件。
我试图弄清楚为什么以下行为在 CUDA 和 C++ 之间不一致。注意x的值是完全一样的,就是static_casting好像不一致。
#include <cstdio>
template<typename RealType>
long long __host__ __device__ __forceinline__ FLOAT_TO_FIXED(RealType v) {
return (long long)(v);
}
void __global__ debug_gpu(double x) {
printf("x %.5f -x %.5f gpu %lld %lld\n", x, -x, FLOAT_TO_FIXED(-x), -FLOAT_TO_FIXED(x));
}
void debug_cpu(double x) {
printf("x %.5f -x %.5f cpu %lld %lld\n", x, -x, FLOAT_TO_FIXED(-x), -FLOAT_TO_FIXED(x));
}
int main() {
double x = static_cast<double>(131154376256114819072.0);
debug_gpu<<<1, 1>>>(x);
cudaDeviceSynchronize();
debug_cpu(x);
}
/*
x 131154376256114819072.00000 -x -131154376256114819072.00000 gpu -9223372036854775808 -9223372036854775807
x 131154376256114819072.00000 -x -131154376256114819072.00000 cpu -9223372036854775808 -9223372036854775808
*/
您似乎在取反 64 位值 -9223372036854775808,这会导致有符号整数溢出(9223372036854775808 的值不能用 64 位有符号整数表示)。这是 C 和 C++ 中的 undefined behavior。这意味着您可以获得任何结果,具体取决于编译器和执行程序的硬件。