符号扩展的必要性是什么?

时间:2012-10-02 14:25:09

标签: c performance optimization sign-extension

考虑下面一段C代码 -

char sum_char(char a,char b)
{
   char c = a+b;
   return c;
}

涉及 -

  1. 将第二个参数转换为符号扩展名。
  2. 将已签名的扩展参数推送到堆栈上,作为b。
  3. 将第一个参数转换为符号扩展名。
  4. 将已签名的扩展参数推送到堆栈上作为。
  5. 添加& b,结果转换为char并将其存储在c。
  6. C再次签名延长。
  7. 符号扩展c被复制到返回值寄存器,函数返回给调用者。
  8. 再次存储结果调用函数将int转换为char。
  9. 我的问题是 -

    1. 是谁做的?
    2. 进行这么多转换的必要性是什么?
    3. 它会降低/提高机器/编译器的性能吗?
    4. 如果它正在降低性能我们应该做些什么才能增加它?

4 个答案:

答案 0 :(得分:2)

您描述的转换仅在抽象机器中执行。如果编译器导致相同的可观察行为,则编译器可以快捷所有这些。

当启用优化时,我的编译器会将其转换为以下汇编程序

sum_char:
.LFB0:
    .cfi_startproc
    leal    (%rsi,%rdi), %eax
    ret
    .cfi_endproc
.LFE0:
    .size   sum_char, .-sum_char

这只是一个添加(隐藏在leal指令中)和ret跳转。

答案 1 :(得分:2)

  1. 谁做到了这一点? - 最终,CPU就是这样做的;编译器生成CPU执行转换的所有相关指令
  2. 进行如此多次转换的必要性是什么? - 转换是确保多个C编译器支持的多个平台的结果一致性所必需的。
  3. 它会降低/提高机器/编译器的性能吗? - 与“无所事事”相比,这会降低性能,但没有人会注意到差异。
  4. 如果它正在降低性能我们应该做些什么来增加它? - 没有:如果你必须在char上执行算术运算,那么你对{{执行算术运算1}}秒。让优化器负责删除平台上所有不必要的指令。在大多数情况下,CPU具有与C语言所需的语义兼容的指令,因此生成的代码将非常短。
  5. 当然,如果您不需要对签名字符执行操作,则可以对无符号字符执行操作。这消除了大量的符号扩展。

答案 2 :(得分:1)

  1. 代码,运行时。编译器生成所需的代码以实现编程语言的指定语义。
  2. 我不确定在你所说的“堆叠”中,据我所知,C中没有这样的要求。
  3. 这没有意义;相比什么?
  4. 您可以尝试删除无意义的c变量,只需return (char) (a + b);。也就是说,我不认为这个功能有很多“优化”。它应编译为非常少的代码。如果你可以把它内联,它可能是1指令的顺序。

答案 3 :(得分:0)

我不确定你问题的细节。您反复提到签名扩展而不引用任何来源;我猜你假设char数据类型将被扩展以匹配CPU的位数,但我认为没有任何保证已经不存在这种情况。

然而,作为回答你模糊问题的一个尝试:

  1. 编译器在响应您编写代码时执行此操作。谁写代码?我想,开发人员。当你写这个问题时,这样做了。
  2. 如果有必要(因为你没有引用你的来源),我想这是因为CPU可以原生地处理算法。
  3. 从技术上讲,它会减少它,但只与具有任意位数的理论机器相比。实际上,它没有明显的区别。
  4. 如果使用与架构的本机位相匹配的数据类型,则会获得非常轻微的性能提升。但是,这非常轻微,通常不值得给您带来不便。