orl*_*rlp -2 c performance gcc micro-optimization
我有两个逻辑上等效的函数:
long ipow1(int base, int exp) {
// HISTORICAL NOTE:
// This wasn't here in the original question, I edited it in,
if (exp == 0) return 1;
long result = 1;
while (exp > 1) {
if (exp & 1) result *= base;
exp >>= 1;
base *= base;
}
return result * base;
}
long ipow2(int base, int exp) {
long result = 1;
while (exp) {
if (exp & 1) result *= base;
exp >>= 1;
base *= base;
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
这些循环是等价的,因为在前一种情况下我们正在返回result * base(处理exp已经或已经减少的情况1)但在第二种情况下我们正在返回result.
奇怪的是,两者都有,-O3并-O0 ipow1因此表现优于ipow2约25%.这怎么可能?
我在Windows 7,x64,gcc 4.5.2和编译gcc ipow.c -O0 -std=c99.
这是我的分析代码:
int main(int argc, char *argv[]) {
LARGE_INTEGER ticksPerSecond;
LARGE_INTEGER tick;
LARGE_INTEGER start_ticks, end_ticks, cputime;
double totaltime = 0;
int repetitions = 10000;
int rep = 0;
int nopti = 0;
for (rep = 0; rep < repetitions; rep++) {
if (!QueryPerformanceFrequency(&ticksPerSecond)) printf("\tno go QueryPerformance not present");
if (!QueryPerformanceCounter(&tick)) printf("no go counter not installed");
QueryPerformanceCounter(&start_ticks);
/* start real code */
for (int i = 0; i < 55; i++) {
for (int j = 0; j < 11; j++) {
nopti = ipow1(i, j); // or ipow2
}
}
/* end code */
QueryPerformanceCounter(&end_ticks);
cputime.QuadPart = end_ticks.QuadPart - start_ticks.QuadPart;
totaltime += (double)cputime.QuadPart / (double)ticksPerSecond.QuadPart;
}
printf("\tTotal elapsed CPU time: %.9f sec with %d repetitions - %ld:\n", totaltime, repetitions, nopti);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
Ben*_*igt 10
不,真的,这两个并不等同. ipow2如果ipow1没有,则返回正确的结果.
PS我不在乎你留下多少评论"解释"为什么它们是相同的,只需要一个反例就可以反驳你的说法.
关于你已经试图向你指出这一点的每个人的令人难以忍受的傲慢的问题的PPS -1.