fre*_*low 100
2的幂除法更快unsigned int
,因为它可以优化为单个移位指令.有了signed int
它,它通常需要更多的机器指令,因为除法向零舍入,但向右舍入向下舍入.例:
int foo(int x, unsigned y)
{
x /= 8;
y /= 8;
return x + y;
}
Run Code Online (Sandbox Code Playgroud)
这是相关x
部分(签名部门):
movl 8(%ebp), %eax
leal 7(%eax), %edx
testl %eax, %eax
cmovs %edx, %eax
sarl $3, %eax
Run Code Online (Sandbox Code Playgroud)
以下是相关y
部分(未签名部门):
movl 12(%ebp), %edx
shrl $3, %edx
Run Code Online (Sandbox Code Playgroud)
ana*_*lyg 18
unsigned
导致相同或更好的表现signed
.一些例子:
signed
数字指令实现它; gcc使用1个指令执行它,就像在这种unsigned
情况下一样)short
通常导致与int
(假设sizeof(short) < sizeof(int)
)相同或更差的表现.当您将算术运算的结果(通常是int
永远的short
)分配给类型的变量时会发生性能下降,该变量short
存储在处理器的寄存器(也是类型int
)中.所有转换short
都int
需要时间并且很烦人.
注意:某些DSP具有signed short
类型的快速乘法指令; 在这种特定情况下short
比...更快int
.
至于int
和之间的区别long
,我只能猜测(我不熟悉64位架构).当然,如果int
并且long
具有相同的大小(在32位平台上),它们的性能也是相同的.
一些非常重要的补充,几个人指出:
对大多数应用程序而言真正重要的是内存占用和带宽利用.对于大型数组short
,您应该使用最小的必要整数(可能是偶数signed/unsigned char
).
这将提供更好的性能,但增益是非线性的(即不是2或4倍)并且有些不可预测 - 它取决于缓存大小以及应用程序中计算和内存传输之间的关系.
sha*_*oth 16
这将取决于具体实施.但在大多数情况下,没有区别.如果您真的在意,您必须尝试所有您考虑的变体并测量性能.
这几乎取决于特定的处理器.
在大多数处理器上,都有有符号和无符号算术的指令,因此使用有符号和无符号整数之间的区别归结为编译器使用的整数.
如果两者中的任何一个更快,那么它完全取决于处理器,如果它存在的话,很可能差别很小.
有符号和无符号整数之间的性能差异实际上比接受答案所暗示的更为普遍.任何常数对无符号整数的划分都可以比有符号整数除以常数更快,无论常数是2的幂.请参见http://ridiculousfish.com/blog/posts/labor-of-division-episode-iii.html
在他的帖子结束时,他包括以下部分:
一个自然的问题是相同的优化是否可以改善签名划分; 不幸的是,它似乎没有,原因有两个:
被除数的增量必须变为幅度的增加,即如果n> 0则增加,如果n <0则递减.这引入了额外的费用.
不合作除数的惩罚只是签名师的一半左右,留下了较小的改进窗口.
因此,似乎可以使得向下舍入算法在有符号的除法中工作,但是将不如标准的向上舍入算法.
使用无符号类型不仅除以 2 的幂更快,而且使用无符号类型除以任何其他值也更快。如果您查看Agner Fog 的指令表,您会发现未签名的除法与签名版本具有相似或更好的性能
以 AMD K7 为例
操作说明 | 操作数 | 行动 | 潜伏 | 吞吐量倒数 |
---|---|---|---|---|
DIV | r8/m8 | 32 | 24 | 23 |
DIV | r16/m16 | 47 | 24 | 23 |
DIV | r32/m32 | 79 | 40 | 40 |
免疫缺陷病毒 | r8 | 41 | 17 号 | 17 号 |
免疫缺陷病毒 | r16 | 56 | 25 | 25 |
免疫缺陷病毒 | r32 | 88 | 41 | 41 |
免疫缺陷病毒 | 米8 | 42 | 17 号 | 17 号 |
免疫缺陷病毒 | 米16 | 57 | 25 | 25 |
免疫缺陷病毒 | 米32 | 89 | 41 | 41 |
同样的情况也适用于英特尔奔腾
操作说明 | 操作数 | 时钟周期 |
---|---|---|
DIV | r8/m8 | 17 号 |
DIV | r16/m16 | 25 |
DIV | r32/m32 | 41 |
免疫缺陷病毒 | r8/m8 | 22 |
免疫缺陷病毒 | r16/m16 | 30 |
免疫缺陷病毒 | r32/m32 | 46 |
当然,这些都是相当古老的。具有更多晶体管的新型架构可能会缩小差距,但基本的事情是适用的:通常您需要更多的微操作、更多的逻辑、更多的芯片面积、更多的延迟来进行有符号除法