调用常数复杂度O(1)5线函数会显着影响性能,为什么?

时间:2014-10-22 10:32:39

标签: c++ performance optimization arduino

我有以下代码:

#include <ros.h>
#include <ros/time.h>
#include <sensor_msgs/Range.h>

#define sensNumber 3
#define firstTrigPin 3
#define firstEchoPin 9

ros::NodeHandle  nh;
sensor_msgs::Range range_msg;
ros::Publisher pub_range( "/ultrasound", &range_msg);
char frameid[] = "/ultrasound";

int trigPin=firstTrigPin;
int echoPin=firstEchoPin;

void increasepins(){
    trigPin++;
    echoPin++;
    if(trigPin>firstTrigPin+sensNumber){
        trigPin=firstTrigPin;
    }
    if(echoPin>firstEchoPin+sensNumber){
        echoPin=firstEchoPin;
    }
}

void setup(){
    nh.initNode();
    nh.advertise(pub_range);
    for(int i=0;i<sensNumber;i++){
        pinMode(trigPin, OUTPUT);
        pinMode(echoPin, INPUT);
        increasepins();  
    }
    range_msg.radiation_type = sensor_msgs::Range::ULTRASOUND;
    range_msg.header.frame_id =  frameid;
    range_msg.field_of_view = 0.1;  
    range_msg.min_range = 0.0;
    range_msg.max_range = 6.47;
}

long range_time;

void loop()
{
    increasepins();
    //publish the adc value every 50 milliseconds
    //since it takes that long for the sensor to stablize
    long duration, distance;
    digitalWrite(trigPin, LOW);  // should be high?
    delayMicroseconds(2); // make this 20
    digitalWrite(trigPin, HIGH);
    delayMicroseconds(10); // reset value?
    digitalWrite(trigPin, LOW);
    distance = pulseIn(echoPin, HIGH)/ 58,2; //sensor constant is 3.4

    range_msg.range = distance;
    range_msg.header.stamp = nh.now();
    range_time =  millis() + 50;
    range_msg.field_of_view = trigPin; 
    range_msg.min_range = echoPin;

    pub_range.publish(&range_msg);

    nh.spinOnce();
}

以上代码在整个循环中以每秒2次的aprox运行在我的funduino上。但是,如果我删除了increasePins方法,它每秒运行大约100次。为什么这个机会很大?看起来像这么简单的一段代码(只增加2个变量然后比较它们)会产生如此大的差异?

作为参考,我们正在谈论这个功能:

void increasepins(){
    trigPin++;
    echoPin++;
    if(trigPin>firstTrigPin+sensNumber){
        trigPin=firstTrigPin;
    }
    if(echoPin>firstEchoPin+sensNumber){
        echoPin=firstEchoPin;
    }
}

与必须等待echo回来并获得时间以及其余代码所需的那些东西相比,对我而言看起来非常简单。

1 个答案:

答案 0 :(得分:1)

我认为其中一个问题是,如果你在循环中注释 increasePins 函数,编译器将决定在循环外部采用一些逻辑。为此,您需要查看汇编代码并查看循环内部的操作。

另一个问题可能与引脚行为有关。例如,我读到“ pulseIn ”函数向引脚发送一个脉冲并测量它的持续时间。你用它来脉冲“echoPin”。我怀疑如果你不改变echoPin,你将有一个相当恒定的持续时间。但是,更改echoPin可能会导致另一个引脚的脉冲持续时间更长的情况。要对此进行测试,当您未对 increasePins 功能发表评论时,可以尝试使用带有超时参数的pulsePin(echoPin, HIGH, timeout)。我希望循环运行得更快。

所以我认为 increasePins 不是瓶颈。我建议将其设为 inline (如果编译器还没有这样做,可以添加一些加速)。