[英]Signed vs Unsigned operations in C
很简单的问题:
我有一个程序在整数和长期内进行大量的数学计算。 为了适应额外的一点,我做了长长的无符号,因为我只处理正数,现在可以得到更多的值。
奇怪的是,这给了我15%的性能提升,我确认只是简单地让所有长长的未签名。
这可能吗? 使用无符号数字,数学运算真的更快吗? 我记得读过没有区别,编译器会自动选择最快的方式,无论是签名还是未签名。 这个15%的提升真的是因为vars没有签名,还是可能是我的代码中的其他东西?
并且,如果它真的是使vars无符号,我应该瞄准使所有(甚至整数)无符号,因为我从不需要负数,如果我可以保存它,每一秒都很重要。
在某些操作中,有符号整数更快,而在其他操作中,无符号整数更快:
在C中,可以假定有符号整数运算不包装。 例如,编译器将在循环优化中利用这一点。 比较可以类似地进行优化。 (如果您不期望这样,这也会导致细微的错误)。
另一方面,无符号整数没有这个假设。 但是,不必处理符号对于某些操作来说是一个很大的优势,例如:除法。 通过2的常数幂进行的无符号除法是一个简单的移位,但是(取决于你的舍入规则)对于负数有一个有条件的除1。
就个人而言,我习惯只使用无符号整数,除非我真的确实有一个需要签名的值。 性能与正确性无关。
您可能会看到长效放大的效果,在我的情况下(我猜)是64位。 CPU通常没有单一指令来处理这些类型(在32位模式下),因此签名操作的轻微增加的复杂性将更加明显。
在32位处理器上,模拟64位整数运算; 使用unsigned
而不是signed
意味着仿真库不需要做额外的工作来传播进位等。
在三种情况下,编译器会关心变量是有符号还是无符号:
在某些机器上,将签名变量转换为更长的类型需要额外的代码; 在其他机器上,转换可以作为“加载”或“移动”指令的一部分来执行。
有些机器(主要是小型嵌入式微控制器)需要更多指令才能执行有符号与无符号无符号比较,但大多数机器都有完整的有符号和无符号比较指令。
当使用无符号类型发生溢出时,编译器可能必须添加代码以确保实际发生定义的行为。 签名类型不需要这样的代码,因为标准允许在没有这些代码的情况下发生的任何事情。
如果编译器未签名或签名,则编译器不会选择。 但是,是的,理论上, unsigned with unsigned
比signed with signed
更快。 如果你真的想减慢速度,那么你将signed with unsigned
。 更糟糕的是: floats with integers
。
当然,这取决于处理器。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.