【问题标题】:reinterpret_cast cast costreinterpret_cast 演员表成本
【发布时间】:2011-04-04 06:21:41
【问题描述】:

我的理解是,C++ reinterpret_cast 和 C 指针强制转换只是 一个编译时功能,而且它根本没有性能成本。

这是真的吗?

【问题讨论】:

    标签: c++ c casting reinterpret-cast


    【解决方案1】:

    这是一个很好的假设。但是,优化器可能会在存在 reinterpret_cast<> 或 C 指针转换的情况下受到限制。然后,即使转换本身没有关联的指令,生成的代码也会变慢。

    例如,如果您将 int 转换为指针,优化器可能不知道该指针可能指向什么。因此,它可能不得不假设通过该指针的写入可以更改任何变量。这胜过非常常见的优化,例如将变量存储在寄存器中。

    【讨论】:

    • 我不认为“通常不是”是您对“这是真的吗?”这个问题的回答。
    • 非常感谢您的回答。也许在那种情况下,人们可能会用 register 关键字(!?)来暗示 GCC。
    • 极不可能。在较旧的实现中,优化器只是将变量分配给寄存器。使用register 将关闭该功能。如今,寄存器分配算法要好得多。例如,他们可以为多个变量重用一个寄存器,并将一个变量分配给一个寄存器仅在其生命周期的一部分内。因此,变量的 register 关键字实际上被忽略了。
    • 鉴于您对优化器看到实际写入的评论,这是否意味着 only 指针类型之间的 reinterpret_cast 将被优化为没有运行时成本?
    • @PLPiper:这可能会损害另一个常见的优化。如果您通过float* 写入然后通过int* 读取,优化器通常可以重新排序这两个语句。写不能影响读,因为类型不同。但是如果在int*float* 之间有一个前面的reinterpret_cast,那么优化器可能会稳妥行事。
    【解决方案2】:

    没错。除了在新宽度上执行指令的性能上的任何增益/损失之外,没有任何成本,我可能会补充,这只是在极少数情况下的一个问题。在我听说过的每个平台上进行指针转换都是零成本,并且没有任何性能变化。

    【讨论】:

      【解决方案3】:

      C++ 中的 C 样式转换将首先尝试 static_cast,并且仅在无法执行静态转换时才执行 reinterpret_cast。在多重继承的情况下(或将接口转换为具体类型时),static_cast 可能会更改指针的值,此偏移量计算可能涉及额外的机器指令。这最多是 1 条机器指令,非常小。

      【讨论】:

        【解决方案4】:

        是的,这是真的。具有运行时开销的转换类型是 dynamic_cast。

        【讨论】:

        • static_cast 也可以有运行时成本;虽然它通常只是一个指针调整,或将一种类型转换为另一种类型的代码(例如将int 转换为float
        • static_cast 不会也调用用户定义的转换吗?这些的运行时成本是无限的。
        • 对,static_cast在类型(不是指针)转换的情况下有运行时开销。我的观点是 dynamic_cast 是唯一具有额外运行时成本的转换类型,相对于 C 转换。
        【解决方案5】:

        你是对的,但请考虑一下:reinterpret_cast 意味着可能是一个糟糕的设计,或者你正在做一些非常低级的事情。

        动态转换反而会让你付出一些代价,因为它必须在运行时查看查找表。

        【讨论】:

        • dynamic_cast 更类似于 static_cast 运行时检查而不是 reinterpret_cast。您不能使用 reinterpreT_cast 强制转换多态类型。
        • @Billy ONeal:你可以但不能多态感知。
        【解决方案6】:

        reinterpret_cast 不会产生运行时成本。但是您必须小心,因为reinterpret_cast 的每次使用都是由实现定义的。例如,将char 数组重新解释为int 数组可能会导致目标架构抛出中断,因为不同的类型可能有不同的对齐规则。

        先做对,再考虑效率。

        【讨论】:

          【解决方案7】:

          在将有符号字符重新解释为无符号字符之前和之后,我都在查看我的汇编代码。指令增加了大约 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 来提高速度。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-05-27
            • 1970-01-01
            • 1970-01-01
            • 2012-08-14
            • 2016-12-18
            • 2015-08-17
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多