有多少 x86 指令组成一个 for 循环迭代?
How many x86 instructions make up a single for loop iteration?
我的任务是生成一个基准程序来估计使用 C 的 x86 系统的 MIPS。我的方法是 运行 一个用于大量迭代的空 for 循环。然后我将测量它的执行时间以确定 MIPS。但是,我需要知道在单个 for 循环迭代中找到的指令数。
#include <stdio.h>
#include <sys/time.h>
int main(int argc, char *argv[])
{
size_t max_iterations = 1000000000;
// grab start time
for(int i = 0; i < max_iterations; i++)
{
// empty
}
// grab end time and calculate MIPS
printf("MIPS = %f\n", max_iterations * instruction_per_cycle / 1000000.0 / elapsed_sec);
return 0;
}
我不熟悉 x86 指令集,但是,对于我提供的 for 循环,似乎以下各项可能是指令:
- 从内存中加载值 i 到寄存器
- 从内存加载值max_iterations到寄存器
- 执行 i 和 max_iterations
之间的比较
- 增加 i
- 将 i 的新值写入内存
- 假设
进入循环
- 跳回到循环语句的开始
我为查看反汇编所做的事情,这可能会帮助您获得所需的东西...
我写了一个简单的函数,在它的主体中有一个普通的 for
循环,并保存到一个文件 for.c
void loop()
{
for(int i = 0; i < 10; i++)
{
// empty
}
}
那我运行
gcc -S for.c
反过来就是让gcc发出汇编代码,结果汇编代码在for.s
中生成。之后我 运行 as
(GNU Assembler) 要求它使用以下命令
生成目标文件 for.o
as -o for.o for.s
生成目标文件 for.o
,此外我还要求实用程序 objdump
使用以下命令向我展示目标文件的反汇编...
objdump -d for.o
它向我展示了这样的输出...
for.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <loop>:
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: c7 45 fc 00 00 00 00 movl [=14=]x0,-0x4(%rbp)
b: eb 04 jmp 11 <loop+0x11>
d: 83 45 fc 01 addl [=14=]x1,-0x4(%rbp)
11: 83 7d fc 09 cmpl [=14=]x9,-0x4(%rbp)
15: 7e f6 jle d <loop+0xd>
17: 90 nop
18: 5d pop %rbp
19: c3 retq
但这也有与堆栈相关的说明,因为我在函数中编写了循环。通常,只有 for for
循环的指令会少于我们当前在反汇编中看到的指令。
x86_64 架构就是我 运行 所有这些,并使用 gcc 编译。所以,请注意您使用的工具。
可能还有其他方法可以达到同样的效果,但现在我可以推荐这种方法,如果它对你有帮助的话。
我的任务是生成一个基准程序来估计使用 C 的 x86 系统的 MIPS。我的方法是 运行 一个用于大量迭代的空 for 循环。然后我将测量它的执行时间以确定 MIPS。但是,我需要知道在单个 for 循环迭代中找到的指令数。
#include <stdio.h>
#include <sys/time.h>
int main(int argc, char *argv[])
{
size_t max_iterations = 1000000000;
// grab start time
for(int i = 0; i < max_iterations; i++)
{
// empty
}
// grab end time and calculate MIPS
printf("MIPS = %f\n", max_iterations * instruction_per_cycle / 1000000.0 / elapsed_sec);
return 0;
}
我不熟悉 x86 指令集,但是,对于我提供的 for 循环,似乎以下各项可能是指令:
- 从内存中加载值 i 到寄存器
- 从内存加载值max_iterations到寄存器
- 执行 i 和 max_iterations 之间的比较
- 增加 i
- 将 i 的新值写入内存
- 假设 进入循环
- 跳回到循环语句的开始
我为查看反汇编所做的事情,这可能会帮助您获得所需的东西...
我写了一个简单的函数,在它的主体中有一个普通的 for
循环,并保存到一个文件 for.c
void loop()
{
for(int i = 0; i < 10; i++)
{
// empty
}
}
那我运行
gcc -S for.c
反过来就是让gcc发出汇编代码,结果汇编代码在for.s
中生成。之后我 运行 as
(GNU Assembler) 要求它使用以下命令
for.o
as -o for.o for.s
生成目标文件 for.o
,此外我还要求实用程序 objdump
使用以下命令向我展示目标文件的反汇编...
objdump -d for.o
它向我展示了这样的输出...
for.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <loop>:
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: c7 45 fc 00 00 00 00 movl [=14=]x0,-0x4(%rbp)
b: eb 04 jmp 11 <loop+0x11>
d: 83 45 fc 01 addl [=14=]x1,-0x4(%rbp)
11: 83 7d fc 09 cmpl [=14=]x9,-0x4(%rbp)
15: 7e f6 jle d <loop+0xd>
17: 90 nop
18: 5d pop %rbp
19: c3 retq
但这也有与堆栈相关的说明,因为我在函数中编写了循环。通常,只有 for for
循环的指令会少于我们当前在反汇编中看到的指令。
x86_64 架构就是我 运行 所有这些,并使用 gcc 编译。所以,请注意您使用的工具。
可能还有其他方法可以达到同样的效果,但现在我可以推荐这种方法,如果它对你有帮助的话。