我尝试减少这个函数的执行时间,结果执行时间降低到了
系统: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);
}
最佳答案
我猜,你在条件表达式中大部分时间都失败了:大多数现代 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 的 64 位算术与 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 个简单的操作,在所有硬件上执行时应该有一个周期的延迟,即。 e.整个循环体的计算时间应该少于12个周期,因此,瓶颈应该是内存总线(这是你无法避免的)。
关于c - 函数的执行时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22112814/