【发布时间】:2014-04-10 15:42:43
【问题描述】:
我写了一个关于3x + 1问题的简单程序,打算告诉跳转指令和条件转移指令之间的区别。
代码在使用标志-O0 编译时运行良好。但是,当我使用-O1 或-O2 标志编译它时,代码似乎陷入了“无限循环”。
您有什么想法可以纠正我的代码以使其正常工作吗?谢谢
g++ 版本
$ g++ --version
g++ (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
编译命令
g++ -std=c++0x -O1 -Wall -g -o "foo" "foo.cc"
这是我的代码。
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <ctime>
using namespace std;
#define print(x) cout << x << endl
#define input(x) cin >> x
#define ENTER "\n\t"
#if defined(__i386__)
static __inline__ unsigned long long rdtsc(void)
{
unsigned long long int x;
__asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
return x;
}
#elif defined(__x86_64__)
static __inline__ unsigned long long rdtsc(void)
{
unsigned hi, lo;
__asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
return ( (unsigned long long)lo)|( ((unsigned long long)hi)<<32 );
}
#endif
const int SIZE = 100000;
int nums[SIZE];
void down_to_one(int v)
{
if (v == 1) {
return;
} else if (v % 2 == 0) {
down_to_one(v >> 1);
} else {
down_to_one(3 * v + 1);
}
}
void down_to_one_asm(int v)
{
if (v == 1) {
return;
}
__asm__ __volatile__(
"movl %0, %%eax" ENTER
"sarl %%eax" ENTER
"leal 1(%0, %0, 2), %%ebx" ENTER
"testl $1, %0" ENTER
"cmovel %%eax, %0" ENTER
"cmovnel %%ebx, %0" ENTER
:"=c"(v)
:"c"(v)
);
down_to_one_asm(v);
}
int main()
{
unsigned long long start, end;
start = rdtsc();
for (int i = 1; i <= SIZE; i++) {
down_to_one(i);
}
end = rdtsc();
print(end - start);
////
__asm__ ("":::"memory");
////
start = rdtsc();
for (int i = 1; i <= SIZE; i++) {
down_to_one_asm(i);
}
end = rdtsc();
print(end - start);
return 0;
}
【问题讨论】:
标签: c++ g++ compiler-optimization inline-assembly