首先,这个问题与for
循环性能无关。这只是背景。
所以,我以某种方式发现,在使用Java时,对for循环进行倒计时要比计算循环快得多。我的意思是,for(int i=0; i < n; i++)
比for(int i=n-1; i >=0; i++)
慢。 (是的,我知道过早优化是所有邪恶的根源,但我只是想找出原因)。所以,这让我觉得差异是因为cmp
在机器级语言中的实现方式。关于本地编写compare
函数的其中一个方法就是这样:
public int compare(int a, int b) {
int diff = a-b;
if(diff == 0) {
return 0;
}
if(b ==0) {
return((is MSD of a 1)?-1:1);
}
return(diff,0);
}
我可以通过按位机大小右移数字来检查MSD位,看看它是1还是0.但是,即使这样,我也需要==
。这将再次回到同样的问题。所以,我的问题是,在汇编或机器级别,<,>,==
如何仅使用按位运算和jmp
序列来实现?
答案 0 :(得分:2)
慢
for(int i=0; i < n; i++)
比for(int i=n-1; i >=0; i++)
不,不是。在它被JITC优化之前它只会慢一些。写一个Caliper或JMH基准来看这个(我前段时间做过)。否则你很可能会完全没有意义(是的,Java基准测试真的很难)。
所以,这让我觉得差异是因为cmp是如何用机器级语言实现的。
后一个循环中没有cmp
。它看起来就像(类似Java的语法)
i--;
if (!zero_flag) goto loop_start;
这是表演胜利的来源。
我能想到的关于本地编写比较函数的方法之一就是这个
不,没有这样的。在大多数CPU上,cmp
指令的工作方式与sub
类似,但无处可写。它只设置标志(零,进位,负数,......),这正是以下条件跳转所使用的。
所有有意义的标记组合都是implemented,即您可以使用单个指令执行任何条件a < b
,a <= b
,....
&lt;,&gt;,==如何使用按位运算和jmp序列实现?
完全没有。那里没有一点点摆弄。
答案 1 :(得分:0)
在机器级别,知道结果是否为零,正或负是“自由操作”。在几乎每个算术运算之后,编译器在“flags”中反映出这一点,在其中可以使用分支指令。因此,您经常尝试将循环安排为完全避免比较指令(即使它很快),并且当某个寄存器通过DECrement操作达到零时,依赖于完成循环的快速。优化编译器应该为您做到这一点,但是这有点奇怪,这应该是显而易见的。