我正在读一本书,作者说这if( a < 901 )比书更快if( a <= 900 ).
与此简单示例不完全相同,但循环复杂代码略有性能变化.我想这必须对生成的机器代码做一些事情,以防它甚至是真的.
使用以下代码是否存在任何执行速度差异:
cmp al, 0
je done
Run Code Online (Sandbox Code Playgroud)
以下内容:
or al, al
jz done
Run Code Online (Sandbox Code Playgroud)
我知道JE和JZ指令是相同的,并且使用OR可以提供一个字节的大小改进.但是,我也关心代码速度.逻辑运算符似乎比SUB或CMP更快,但我只是想确定.这可能是规模和速度之间的权衡,或双赢(当然代码将更加不透明).
这可能是一个愚蠢的问题,但这种优化有时会提高应用程序的性能.在这里我要专门讨论C++,因为C++编译代码的方式与c#或Java有很大不同.
问题是哪一个表现更好,如果变量i是int.
i > -1i >= 0我正在寻找所需的内存块或寄存器性能以及两种条件所需的CPU周期.
提前致谢.
addiu $6,$6,5
bltz $6,$L5
nop
...
$L5:
Run Code Online (Sandbox Code Playgroud)
除了缓存未命中,经典 MIPS 甚至无法做到这一点,而不会出现停顿,这如何安全?(MIPS 最初代表没有互锁流水线级的微处理器,并且有一个加载延迟槽而不是互锁。)
原始 MIPS I 是经典的 5 阶段 RISCIF ID EX MEM WB设计,通过在 ID 阶段及早检查分支条件,通过单个分支延迟槽隐藏其所有分支延迟(更正:这是错误,请阅读此答案;不要不要被基于这个错误前提的问题中的其他细节所误导)。这就是为什么它仅限于等于/不等于或符号位检查(如 lt 或 ge 零),而不是两个需要通过加法器进行进位传播的寄存器之间的 lt。
这是否意味着分支需要比 ALU 指令早一个周期准备好输入? 的bltz进入,所述同一周期ID阶段addiu进入EX。
MIPS I(又名 R2000)使用从 EX 输出到 EX 输入的旁路转发,因此普通整数 ALU 指令(如addu/链xor)具有单周期延迟并且可以在连续周期中运行。
MIPS 代表“没有互锁流水线阶段的微处理器”,因此它不检测 RAW 危害;代码必须避免它们。(因此,第一代 MIPS 上的加载延迟插槽,在这种情况下,MIPS II 添加了互锁以停止,使首字母缩略词:P 无效)。
但是我从来没有看到任何关于计算分支条件多条指令以避免停顿的讨论。(addiu/bltz 示例是由 MIPS gcc5.4-O3 -march=mips1 在Godbolt上发出的,它确实尊重加载延迟槽,nop …
回到我学习C和装配的那一天,我们被教导,最好使用简单的比较来提高速度.例如,如果你说:
if(x <= 0)
Run Code Online (Sandbox Code Playgroud)
与
if(x < 1)
Run Code Online (Sandbox Code Playgroud)
哪个会执行得更快?我的论点(可能是错误的)是第二个几乎总是执行得更快,因为只有一个比较)即小于一,是或否.
如果数字小于0,第一个将快速执行,因为这等于为真,没有必要检查等于使得它与第二个一样快,但是,如果数字为0或更多,它将总是更慢,因为它然后必须进行第二次比较,看它是否等于0.
我现在正在使用C#,而在开发台式机时速度不是问题(至少没有达到他的观点值得争论的程度),我仍然认为这些论点需要考虑因为我也在为移动设备开发功能不如台式机,速度确实成为这类设备的问题.
为了进一步考虑,我说的是整数(没有小数)和数字,其中不能有负数如-1或-12,345等(除非有错误),例如,当你不能处理列表或数组时有一个负数的项目,但你想检查一个列表是否为空(或如果有问题,将x的值设置为负表示错误,一个例子是列表中有一些项目,但你不能由于某种原因检索整个列表,并指出你将数字设置为负数,这与说没有项目是不一样的).
由于上述原因,我故意忽略了显而易见的事实
if(x == 0)
Run Code Online (Sandbox Code Playgroud)
和
if(x.isnullorempty())
Run Code Online (Sandbox Code Playgroud)
用于检测没有项目的列表的其他此类项目.
同样,为了考虑,我们讨论的是从数据库中检索项目的可能性,可能使用具有所述功能的SQL存储过程(即标准(至少在该公司中)是返回负数以指示问题).
所以在这种情况下,使用上面的第一个或第二个项目会更好吗?