执行函数的时间

时间:2014-03-01 09:58:02

标签: c performance optimization profiling

我尝试减少此功能的执行时间,并将执行时间缩短为

SYS:0.001S

有没有办法进一步减少这个功能的执行时间?

 int function(uint32_t *r, const uint32_t *a, const uint32_t *b, int n)
   {
      int i;
      uint32_t ri, c=0;
      for (i = 0; i < n; i ++)
          {
             ri = a[i] + b[i] + c;
             c = ((ri < a[i]) || ((ri == a[i]) && c));
             r[i] = ri;
          }
      return ((int) c);
   }

3 个答案:

答案 0 :(得分:1)

我想,你在条件表达式中大部分时间都处于松散状态:如果大多数时候他们无法正确预测,大多数现代CPU讨厌分支。因此,大多数循环引入的分支都很好,因为它们只对整个循环进行了一次错误预测。然而,在携带条件下进行分支可能会导致50%的分支被错误预测,并且每次错误预测都值10到20个周期。更糟糕的是,&&||运算符是序列点,这是优化器的障碍。

所以,我会尝试消除这些条件:

int function(uint32_t *r, const uint32_t *a, const uint32_t *b, int n) {
    int i;
    uint64_t ri, c=0;
    for (i = 0; i < n; i ++) {
        ri = (uint64_t)a[i] + (uint64_t)b[i] + c;
        c = ri >> 32;
        r[i] = (uint32_t)ri;
    }
    return ((int) c);
}

这里,我使用了64位运算,因为现代CPU的运算速度与32位运算一样快。但是,如果硬件上的64位算术速度很慢,则可以回退到32位算术:

int function(uint32_t *r, const uint32_t *a, const uint32_t *b, int n) {
    int i;
    uint32_t ri, c=0;
    for (i = 0; i < n; i ++) {
        uint32_t curA = a[i], curB = b[i];
        uint32_t lowA = curA & 0xffffu, highA = curA >> 16;
        uint32_t lowB = curB & 0xffffu, highB = curB >> 16;
        uint32_t lowR = lowA + lowB + c;
        uint32_t highR = highA + highB + (lowR >> 16);
        c = highR >> 16;
        r[i] = (highR << 16) + lowR;
    }
    return ((int) c);
}

即使这看起来像一个怪物,它只有12个简单的操作,应该在所有硬件上以一个周期的延迟执行,i。即整个循环体的计算应该少于12个循环,因此,瓶颈应该是内存总线(你无法避免)。

答案 1 :(得分:0)

你可以摆脱下标符号并使用指针运算代替据说更快,但我不知道实际节省多少CPU时间。

 int function(uint32_t *r, const uint32_t *a, const uint32_t *b, int n)
   {
      int i;
      uint32_t ri, c=0;
      for (i = 0; i < n; i ++)
          {
             ri = *(a + i) + *(b + i) + c;
             c = ((ri < *(a + i)) || ((ri == *(a +i)) && c));
             *(r + i) = ri;
          }
      return ((int) c);
   }

原因见:Accessing array values via pointer arithmetic vs. subscripting in C

答案 2 :(得分:0)

c =(ri&lt; a [i])+((ri-a [i])* c)可能比你的代码更快,如果c == 0

也会测试