在非Cuda C ++代码中,当前建议的做法是应该使用通过memcpy的类型惩罚,而不是通过联合使用UB。尽管它可能会导致Debug版本中出现性能问题,但事实上我必须使用UB root来在Release版本中获得更好的性能。
Cuda的推荐做法是什么?并且它总是不幸地在Debug构建中调用memcpy()吗?
答案 0 :(得分:1)
所以我对此感到好奇,并在编译器资源管理器中进行了查看 https://godbolt.org/z/Cv5ozC 似乎cuda会执行完整的memcpy。 没有一般性建议,但是我们可以使用std :: bit_cast从c ++ 20标准中学到一些东西。我认为采用std :: bit_cast的实现并更改胆量以重新解释演员表是最好的方法。它仍然是未定义的行为,但是您正在为单个体系结构进行编译,因此至少会始终未定义。并增加了许多未定义的行为路线所允许的白痴证明。
template <class To, class From, class Res = typename std::enable_if<
(sizeof(To) == sizeof(From)) &&
(alignof(To) == alignof(From)) &&
std::is_trivially_copyable<From>::value &&
std::is_trivially_copyable<To>::value,
To>::type>
__device__ Res& bit_cast(From& src) noexcept {
return *reinterpret_cast<To*>(&src);
}
仍然没有将float [4]转换为float4的好方法,因为类型系统无法表示指向数组开头的指针满足float4的对齐要求。
如果您想了解更多信息,我通过观看CPPCon2019的演讲来了解这一点:https://www.youtube.com/watch?v=_qzMpk-22cc