Den*_*er9 1 c optimization loops micro-optimization compiler-optimization
我在 C 中有一个这样的函数(在伪代码中,删除不重要的部分):
int func(int s, int x, int *a, int *r) {
int i;
// do some stuff
for (i = 0; i < a_really_big_int; ++i) {
if (s)
r[i] = x ^ i;
else
r[i] = x ^ a[i];
// and maybe a couple other ways of computing r
// that are equally fast individually
}
// do some other stuff
}
Run Code Online (Sandbox Code Playgroud)
这段代码被调用得太多,以至于这个循环实际上是代码中的速度瓶颈。我想知道几件事:
由于 switchs是函数中的常量,好的编译器会优化循环,以便分支不会一直减慢速度吗?
如果没有,优化这段代码的好方法是什么?
====
编辑:这是一个包含更完整示例的更新:
int func(int s,
int start, int stop, int stride,
double *x, double *b,
int *a, int *flips, int *signs, int i_max,
double *c)
{
int i,k,st;
for (k=start; k<stop; k += stride) {
b[k] = 0;
for (i=0;i<i_max;++i) {
/* this is the code in question */
if (s) st = k^flips[i];
else st = a[k]^flips[i];
/* done with code in question */
b[k] += x[st] * (__builtin_popcount(st & signs[i])%2 ? -c[i] : c[i]);
}
}
}
Run Code Online (Sandbox Code Playgroud)
编辑2:
如果有人好奇,我最终重构了代码并将整个内部 for 循环(带有i_max)提升到外面,使really_big_int循环变得更加简单,并且希望易于矢量化!(并且还避免无数次执行一堆额外的逻辑)
优化代码的一种明显方法是将条件拉到循环之外:
if (s)
for (i=0;i<a_really_big_int;++i) {
r[i] = x ^ i;
}
else
for (i=0;i<a_really_big_int;++i) {
r[i] = x ^ a[i];
}
Run Code Online (Sandbox Code Playgroud)
精明的编译器也许能够将其更改为一次多个元素的 r[] 赋值。