【发布时间】:2011-04-04 06:21:41
【问题描述】:
我的理解是,C++ reinterpret_cast 和 C 指针强制转换只是 一个编译时功能,而且它根本没有性能成本。
这是真的吗?
【问题讨论】:
标签: c++ c casting reinterpret-cast
我的理解是,C++ reinterpret_cast 和 C 指针强制转换只是 一个编译时功能,而且它根本没有性能成本。
这是真的吗?
【问题讨论】:
标签: c++ c casting reinterpret-cast
这是一个很好的假设。但是,优化器可能会在存在 reinterpret_cast<> 或 C 指针转换的情况下受到限制。然后,即使转换本身没有关联的指令,生成的代码也会变慢。
例如,如果您将 int 转换为指针,优化器可能不知道该指针可能指向什么。因此,它可能不得不假设通过该指针的写入可以更改任何变量。这胜过非常常见的优化,例如将变量存储在寄存器中。
【讨论】:
register 将关闭该功能。如今,寄存器分配算法要好得多。例如,他们可以为多个变量重用一个寄存器,并将一个变量分配给一个寄存器仅在其生命周期的一部分内。因此,变量的 register 关键字实际上被忽略了。
float* 写入然后通过int* 读取,优化器通常可以重新排序这两个语句。写不能影响读,因为类型不同。但是如果在int* 和float* 之间有一个前面的reinterpret_cast,那么优化器可能会稳妥行事。
没错。除了在新宽度上执行指令的性能上的任何增益/损失之外,没有任何成本,我可能会补充,这只是在极少数情况下的一个问题。在我听说过的每个平台上进行指针转换都是零成本,并且没有任何性能变化。
【讨论】:
C++ 中的 C 样式转换将首先尝试 static_cast,并且仅在无法执行静态转换时才执行 reinterpret_cast。在多重继承的情况下(或将接口转换为具体类型时),static_cast 可能会更改指针的值,此偏移量计算可能涉及额外的机器指令。这最多是 1 条机器指令,非常小。
【讨论】:
是的,这是真的。具有运行时开销的转换类型是 dynamic_cast。
【讨论】:
static_cast 也可以有运行时成本;虽然它通常只是一个指针调整,或将一种类型转换为另一种类型的代码(例如将int 转换为float)
static_cast 不会也调用用户定义的转换吗?这些的运行时成本是无限的。
你是对的,但请考虑一下:reinterpret_cast 意味着可能是一个糟糕的设计,或者你正在做一些非常低级的事情。
动态转换反而会让你付出一些代价,因为它必须在运行时查看查找表。
【讨论】:
dynamic_cast 更类似于 static_cast 运行时检查而不是 reinterpret_cast。您不能使用 reinterpreT_cast 强制转换多态类型。
reinterpret_cast 不会产生运行时成本。但是您必须小心,因为reinterpret_cast 的每次使用都是由实现定义的。例如,将char 数组重新解释为int 数组可能会导致目标架构抛出中断,因为不同的类型可能有不同的对齐规则。
先做对,再考虑效率。
【讨论】:
在将有符号字符重新解释为无符号字符之前和之后,我都在查看我的汇编代码。指令增加了大约 3 或 4 条指令。
int main()
{
signed char i = 0x80;
(unsigned char&)i >>= 7;
return i;
}
我正在转换为 unsigned char 以使编译器使用 SHL 指令,而不是 SAR 指令,因此新移位的位移将是 zer0s 而不是 var i 有符号位值。
编译器仍然并且似乎总是使用 SAR 指令。但是重新解释强制转换使编译器添加了更多指令。还有 3 到 4 条指令!
我担心为什么我将 UTF8 转换为 UTF16 字符串的 unicode 函数比 Win32 MultiByteToWideChar() 慢了近 3 倍。现在我担心选角是主要因素之一。
这很讽刺,因为我们使用 reinterpret cast 来提高速度。
【讨论】: