Cortex M3,gcc-C中更快的边界

问题描述

我试图限制c中2个整数之间的差;本质上是绝对值(a-b)

  if (abs( a - b) < bound)
    {
      .........
    }

或者我是否应该进行两次比较:

    int diff;
    diff = a - b;
    if ((bound > diff) && (bound > -diff))
    {
     .......
    }

我知道这与编译器优化和Arm指令集有很大关系,因此我无法随意确定。

谢谢

解决方法

只需尝试

#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 bound )
{
    int diff;
    diff = a - b;
    if ((bound > diff) && (bound > (-diff)))
    {
        return(1);
    }
    return(0);
}
unsigned int fun2 ( int a,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,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,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        nop

fun0和fun2是相同数量的指令,没有分支,利用了条件执行(但结果可能没有明显的赢家)。中间的一个(您的选择)会引起分支,但路径较短,因此在这种情况下很难称其为失败者。 9条或5条指令(包括分支)与9条和9条相比。

目标不同,结果可能会不同。

另一种方法:

#include <stdlib.h>
int funct(int a,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,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,r1
  1a:   1a09        suble   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

第二种解决方案的路径较少,但会产生分支,另一条路径较长。

,

两者都是未定义的行为。减法可能溢出。您需要检查注释中提到的@ e2-e4,该注释较大且相减。 gcc会很好地对其进行优化。

int funct(int a,int c)
{
  if (abs(a > b ? a-b : b-a) < bound) c = 5;

    return c;
}

int funct2(const int a,int c) 
{
    int diff;
    diff = a > b ? a-b : b-a;
    if ((bound > diff) && (bound > -diff)) c = 4;
    return c;
}

两者都编译完全相同的代码。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...