我正在尝试限定c中两个整数之间的差;本质上是绝对值( a- b) <界限。有没有人知道,对于Arm Cortex gcc编译器,如果我取一个差的绝对值会更好:
if (abs( a - b) < bound)
{
.........
}或者我应该做两个比较:
int diff;
diff = a - b;
if ((bound > diff) && (bound > -diff))
{
.......
}我知道这与编译器优化和Arm指令集有很大关系,所以这不是我可以随便确定的。
谢谢
发布于 2020-08-17 05:26:07
就试一下
#include <stdlib.h>
unsigned int fun0 ( int a, int b, int bound )
{
if (abs( a - b) < bound)
{
return(1);
}
return(0);
}
unsigned int fun1 ( int a, int b, int bound )
{
int diff;
diff = a - b;
if ((bound > diff) && (bound > (-diff)))
{
return(1);
}
return(0);
}
unsigned int fun2 ( int a, int b, int bound )
{
int diff;
diff = a > b ? a-b : b-a;
if(diff < bound)
{
return(1);
}
return(0);
}“gcc”的一个版本
Disassembly of section .text:
00000000 <fun0>:
0: 1a40 subs r0, r0, r1
2: 2800 cmp r0, #0
4: bfb8 it lt
6: 4240 neglt r0, r0
8: 4290 cmp r0, r2
a: bfac ite ge
c: 2000 movge r0, #0
e: 2001 movlt r0, #1
10: 4770 bx lr
12: bf00 nop
00000014 <fun1>:
14: 1a41 subs r1, r0, r1
16: 4291 cmp r1, r2
18: da05 bge.n 26 <fun1+0x12>
1a: 4249 negs r1, r1
1c: 4291 cmp r1, r2
1e: bfac ite ge
20: 2000 movge r0, #0
22: 2001 movlt r0, #1
24: 4770 bx lr
26: 2000 movs r0, #0
28: 4770 bx lr
2a: bf00 nop
0000002c <fun2>:
2c: 4288 cmp r0, r1
2e: bfcc ite gt
30: 1a40 subgt r0, r0, r1
32: 1a08 suble r0, r1, r0
34: 4290 cmp r0, r2
36: bfac ite ge
38: 2000 movge r0, #0
3a: 2001 movlt r0, #1
3c: 4770 bx lr
3e: bf00 nopfun0和fun2是相同数量的指令,没有分支,利用条件执行(如果没有条件执行,结果可能会有明确的赢家)。中间的,你的选择,产生一个分支,但有一条更短的路径,所以在这种情况下很难称之为失败者。9或5条指令(包括分支)与9和9相比。
不同的目标,结果可能不同。
另一种方法:
#include <stdlib.h>
int funct(int a, int b, int bound, int c)
{
if (abs(a-b) < bound) c = 5;
return c;
}
int funct2(const int a, const int b, const int bound, int c)
{
int diff;
diff = a > b ? a-b : b-a;
if ((bound > diff) && (bound > -diff)) c = 4;
return c;
}
00000000 <funct>:
0: 1a40 subs r0, r0, r1
2: 2800 cmp r0, #0
4: bfb8 it lt
6: 4240 neglt r0, r0
8: 4290 cmp r0, r2
a: bfac ite ge
c: 4618 movge r0, r3
e: 2005 movlt r0, #5
10: 4770 bx lr
12: bf00 nop
00000014 <funct2>:
14: 4288 cmp r0, r1
16: bfcc ite gt
18: 1a41 subgt r1, r0, r1
1a: 1a09 suble r1, r1, r0
1c: 4291 cmp r1, r2
1e: da03 bge.n 28 <funct2+0x14>
20: 4249 negs r1, r1
22: 4291 cmp r1, r2
24: bfb8 it lt
26: 2304 movlt r3, #4
28: 4618 mov r0, r3
2a: 4770 bx lr第二种解决方案的路径具有较少的指令,但会导致分支,另一条路径较长。
发布于 2020-08-16 22:11:55
两者都是未定义的行为。减法可能会溢出。你需要检查评论中提到的@e2-e4,它更大,更小。它将被gcc很好地优化。
int funct(int a, int b, int bound, int c)
{
if (abs(a > b ? a-b : b-a) < bound) c = 5;
return c;
}
int funct2(const int a, const int b, const int bound, int c)
{
int diff;
diff = a > b ? a-b : b-a;
if ((bound > diff) && (bound > -diff)) c = 4;
return c;
}两者都编译完全相同的代码。
https://stackoverflow.com/questions/63437281
复制相似问题