繁体   English   中英

C中的签名与未签名操作

[英]Signed vs Unsigned operations in C

很简单的问题:

我有一个程序在整数和长期内进行大量的数学计算。 为了适应额外的一点,我做了长长的无符号,因为我只处理正数,现在可以得到更多的值。

奇怪的是,这给了我15%的性能提升,我确认只是简单地让所有长长的未签名。

这可能吗? 使用无符号数字,数学运算真的更快吗? 我记得读过没有区别,编译器会自动选择最快的方式,无论是签名还是未签名。 这个15%的提升真的是因为vars没有签名,还是可能是我的代码中的其他东西?

并且,如果它真的是使vars无符号,我应该瞄准使所有(甚至整数)无符号,因为我从不需要负数,如果我可以保存它,每一秒都很重要。

在某些操作中,有符号整数更快,而在其他操作中,无符号整数更快:

  • 在C中,可以假定有符号整数运算不包装。 例如,编译器将在循环优化中利用这一点。 比较可以类似地进行优化。 (如果您不期望这样,这也会导致细微的错误)。

  • 另一方面,无符号整数没有这个假设。 但是,不必处理符号对于某些操作来说是一个很大的优势,例如:除法。 通过2的常数幂进行的无符号除法是一个简单的移位,但是(取决于你的舍入规则)对于负数有一个有条件的除1。

就个人而言,我习惯只使用无符号整数,除非我真的确实有一个需要签名的值。 性能与正确性无关。

您可能会看到长效放大的效果,在我的情况下(我猜)是64位。 CPU通常没有单一指令来处理这些类型(在32位模式下),因此签名操作的轻微增加的复杂性将更加明显。

在32位处理器上,模拟64位整数运算; 使用unsigned而不是signed意味着仿真库不需要做额外的工作来传播进位等。

在三种情况下,编译器会关心变量是有符号还是无符号:

  1. 当变量转换为更长的类型时
  2. 当应用比较运算符(大于等)时
  3. 何时可能发生溢出

在某些机器上,将签名变量转换为更长的类型需要额外的代码; 在其他机器上,转换可以作为“加载”或“移动”指令的一部分来执行。

有些机器(主要是小型嵌入式微控制器)需要更多指令才能执行有符号与无符号无符号比较,但大多数机器都有完整的有符号和无符号比较指令。

当使用无符号类型发生溢出时,编译器可能必须添加代码以确保实际发生定义的行为。 签名类型不需要这样的代码,因为标准允许在没有这些代码的情况下发生的任何事情。

如果编译器未签名或签名,则编译器不会选择。 但是,是的,理论上, unsigned with unsignedsigned with signed更快。 如果你真的想减慢速度,那么你将signed with unsigned 更糟糕的是: floats with integers

当然,这取决于处理器。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM