需要优化串行数据传输

时间:2017-06-23 20:48:23

标签: c++ serial-port serial-communication

我目前的职能是:

void Path(Point j){
   if(j.y > 0 && j.y <= a){
      char moveMsg[1] = {'j'};
      write(fd1, moveMsg, 1);
   }
   else if(j.y > a && j.y <= b){
      char moveMsg[1] = {'i'};
      write(fd1, moveMsg, 1);
   }
   else if(j.y > b && j.y <= c){
      char moveMsg[1] = {'h'};
      write(fd1, moveMsg, 1);
   }
   else if(j.y > c && j.y <= d){
      char moveMsg[1] = {'g'};
      write(fd1, moveMsg, 1);
   }
   else if(j.y > d && j.y <= e){
      char moveMsg[1] = {'f'};
      write(fd1, moveMsg, 1);
   }
   else if(j.y > e && j.y <= f){
      char moveMsg[1] = {'e'};
      write(fd1, moveMsg, 1);
   }
   else if(j.y > f && j.y <= g){
      char moveMsg[1] = {'d'};
      write(fd1, moveMsg, 1);
   }
   else if(j.y > g && j.y <= h){
      char moveMsg[1] = {'c'};
      write(fd1, moveMsg, 1);
   }
   else if(j.y > h && j.y <= i){
      char moveMsg[1] = {'b'};
      write(fd1, moveMsg, 1);
   }
   else if(j.y > i && j.y <= r){
      char moveMsg[1] = {'a'};
      write(fd1, moveMsg, 1);
   }
}

间隔是预定义的int,我尝试在函数外部初始化char moveMsg,然后在里面重新定义它,它给了我很多错误。我测试了几种不同的串行通信方法,它们都给了我相似的时间,但现在我只需要减少几毫秒,所以如果有人知道更快的方法,那就太棒了。

谢谢!

1 个答案:

答案 0 :(得分:0)

  • 如果变量abc,... ir的整数值单调递增,那么 if 条件可以优化。
  • 可以针对局部缩放器变量优化结构元素和数组元素的重复访问。
  • 重复分配&amp;为了时间优化,可以消除局部变量的解除分配。
  • 可以消除 write()系统调用的重复,以实现空间优化和代码可维护性。

  • 二进制比较算法可以改进顺序比较 而不是最多执行10个 if 语句,最大值可以是4(加上系统调用的布尔测试)。
    原始代码在每个 if 中有两个整数比较和一个逻辑运算(并不昂贵),但可以优化为每个 if 中的一个比较。

以下(经过测试和)可能是空间和时间的最佳选择。

void Path(Point j)
{
   int val = j.y;
   char moveMsg = 0;

   /* ASSERT(0 < a < b < c < d < e < f < g < h < i < r) */

   if (val <= e) {
      if (val <= b) {
         if (val <= a) {
            if (val > 0)   /* && val <= a */
               moveMsg = 'j';
         } else    /* val <= b && val > a */
            moveMsg = 'i';
      } else {  
         if (val <= c)      /* && val > b */
            moveMsg = 'h';
         else if (val <= d) /* && val > c */
            moveMsg = 'g';
         else      /* val <= e && val > d */
            moveMsg = 'f';
      }
   } else {
      if (val <= h) {
         if (val <= f)      /* && val > e */
            moveMsg = 'e';
         else if (val <= g) /* && val > f */
            moveMsg = 'd';
         else      /* val <= h && val > g */
            moveMsg = 'c';    
      } else {
         if (val <= i)      /* && val > h */
            moveMsg = 'b';
         else if (val <= r) /* && val > i */
            moveMsg = 'a';
      }
   }

   if (moveMsg)
      write(fd1, &moveMsg, 1);
}

节省的时间在很大程度上取决于输入值的分布。如果数据偏低,则节省的成本很小,而如果数据偏向大值或均匀分布,那么节省的成本会更高。
执行时间的变化也不再是输入值的函数;当然,对于整数比较,这种变化并不大。

  

...接收代码已经过优化,而在此段中运行大约需要600个时钟周期,我觉得它可以从中减少。

除了二进制算法之外,这些都是众所周知的优化,良好的优化编译器可以为您执行这些优化 由于手动优化变得无用/失去技能,我倾向于怀疑你的主张&#34;接收代码已经过优化&#34; 。 最好的优化是正确的算法和正确使用系统调用(例如,只写一个字节的系统调用将占用此例程的大部分执行时间)。

附录

  

你能解释一下为什么你这样做的if语句吗?为什么要通过更多if语句来帮助它更快?

优化后的代码有11个 if 语句来查找范围;只有一个&#34;更多&#34; 而不是原始代码。
此外,每个 if 语句只是一个简单的整数比较,而不是原始的两个比较的复合逻辑表达式。
就实际ALU操作的数量而言(而不是源代码复杂性)而言,原始代码显然比执行代码更昂贵 优化代码。

优化后的代码通常可以执行更少(不多于) if 语句,并执行比原始代码更少的比较。
原始代码的明显简单性具有众所周知的低效率,因为它采用线性或顺序(即一个接一个)搜索。

当输入值等于最大值r时,会出现原始代码的最坏情况 那时原始代码必须执行所有10个 if 语句并执行20次整数比较 优化后的代码使用binary search执行4 if 语句,并对同一输入仅执行4次整数比较。
优化代码的最坏情况是执行4 if 语句并执行4次整数比较。

当输入值等于最小值a时,会出现原始代码的最佳情况 原始代码只需要执行1 if 语句,但这确实涉及2个整数比较 优化后的代码将执行4 if 语句,并对同一输入执行4次整数比较 这只是另外2次比较,它是影响执行时间的比较次数,而不是源代码中 if 语句的数量。
对这一最佳案例进行两次比较的惩罚被最坏情况下16次较少比较的显着优势所抵消。

平均情况使用二分搜索支持优化代码 执行10次整数比较的原始5 if 语句比优化的4 if 语句执行仅4次整数比较要慢。
这是6次整数比较的优势。

实际上除非输入值始终不超过a(即第一个间隔),否则优化代码将执行与原始代码相同或更少的整数比较,尽管看起来有更多 if 语句。

  

这对我来说似乎违反直觉。

使用搜索(和排序)算法,简单或直接通常意味着缓慢。