首页 > 解决方案 > 有多少 x86 指令组成一个 for 循环迭代?

问题描述

我的任务是生成一个基准程序,该程序使用 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 循环,似乎以下项目可能是指令:

  1. 将值 i 从内存加载到寄存器
  2. 将值 max_iterations 从内存加载到寄存器
  3. 在 i 和 max_iterations 之间进行比较
  4. 增加 i
  5. 将 i 的新值写入内存
  6. 跳入循环假设
  7. 跳回到循环语句的开头

标签: assemblyx86benchmarking

解决方案


我为查看反汇编所做的事情可能会帮助您获得所需的东西...

我写了一个简单的函数,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   $0x0,-0x4(%rbp)
   b:   eb 04                   jmp    11 <loop+0x11>
   d:   83 45 fc 01             addl   $0x1,-0x4(%rbp)
  11:   83 7d fc 09             cmpl   $0x9,-0x4(%rbp)
  15:   7e f6                   jle    d <loop+0xd>
  17:   90                      nop
  18:   5d                      pop    %rbp
  19:   c3                      retq

但这也有与堆栈相关的指令,因为我在函数中编写了循环。通常,只有 forfor循环会比我们当前在反汇编中看到的指令少。

x86_64 架构是我运行所有这些的地方,并使用 gcc 进行编译。因此,请注意您使用的工具。

可能还有其他方法可以实现相同的目标,但现在我可以建议这种方式,如果它对你有帮助的话。


推荐阅读