g++内联asm在使用优化标志时未按预期工作
g++ inline asm not working as expected with optimization flag
我写了一个关于3x + 1
问题的简单程序,打算告诉跳转指令和条件转移命令之间的区别。
当使用标志-O0
编译时,代码运行良好。然而,当我用-O1
或-O2
标志编译它时,代码似乎陷入了"无限循环"。
你有什么想法来纠正我的代码使其工作吗?thx
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 "nt"
#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;
}
您还没有指定无限循环发生的位置。一个潜在的问题来源是down_to_one_asm
函数。您还需要指定您已删除的寄存器,例如
: "=c" (v) : "c" (v) : "%eax", "%ebx"
您可能可以使用"-O0"
,但更高级别可能正在优化调用堆栈/帧设置,而"-O2"
(IIRC)正在实现尾调用优化。
相关文章:
- QSqlquery prepare()和bindvalue()不工作
- 导入库可以跨dll版本工作吗
- 以螺旋方式打印矩阵的程序.(工作不好)
- 对象指针在c++中是如何工作的
- 为什么在Windows上的VS 2019和Clang 9中"size_t"在没有标题的情况下工作
- VSOMEIP-2个设备之间的通信(TCP/UDP)不工作
- 为字符串中每 N 个字符插入空格的函数没有按照我认为的方式工作?
- C++为线程工作动态地分割例程
- 为什么我的 std::ref 无法按预期工作?
- 布尔比较运算符是如何在C++中工作的
- 使用 std::atomic 标志和 std::condition_variable 在工作线程上等待
- 为什么我必须将错误状态标志设置为 goodbit 才能使其工作
- 为什么一些 GCC 警告标志不属于C++语言,但在C++中工作
- I/O流标志是如何工作的
- Android OpenCV imread 标志致命异常,imread 在没有标志的情况下工作正常,像素输出与 MATLAB 不匹配
- make OBJECT文件标志不工作
- 调用WinHttpCreateUrl与ICU_REJECT_USERPWD标志设置在Windows 7中工作,但不Win
- g++内联asm在使用优化标志时未按预期工作
- 打开CV标志不工作
- 编译ncurses代码与GCC -lncurses标志似乎不工作