每个C指令有多少个asm指令?

时间:2008-12-01 16:54:30

标签: c assembly instructions

我意识到这个问题绝对不可能回答,但我只是在大概数字之后:

给定一个合理大小的C程序(数千行代码),平均来说,将生成多少个ASM指令。换句话说,什么是真实的C-to-ASM指令比率?随意做出假设,例如“使用当前的x86架构”。

我曾尝试谷歌这个,但我找不到任何东西。

附录:注意到这个问题引起了多大的混淆,我觉得有些需要解释:我想通过这个答案知道,实际上是要知道“3GHz”意味着什么。我完全清楚Herz的吞吐量差别很大,具体取决于架构,硬件,缓存,总线速度和月球位置。

我不是在一个精确而科学的答案之后,而是一个可以用于最终尺度的经验答案。

这不是一个简单的答案(正如我注意到的那样),这是我最大的努力。我知道每行C的ASM行数量取决于你在做什么。 i++sqrt(23.1)不在同一个社区 - 我知道这一点。此外,无论我从C中获得什么ASM,ASM都被解释为处理器内的各种微码集,这再次取决于您是运行AMD,英特尔还是其他东西,以及它们各自的代。我也知道这一点。

到目前为止,我所得到的球场答案是我所追求的:一个足够大的项目平均每1行ANSI-C约2行x86 ASM。今天的处理器可能会在每个时钟周期平均大约一个ASM命令,一旦管道被填满,并给出足够大的样本。

8 个答案:

答案 0 :(得分:21)

没有可能的答案。像int a;这样的语句可能需要零asm行。而像a = call_is_inlined();这样的语句可能需要20多个asm行。

您可以通过编译c程序,然后启动objdump -Sd ./a.out来看待自己。它将显示asm和C代码混合,因此您可以看到为一个C行生成了多少asm行。例如:

test.c的

int get_int(int c);
int main(void) {
    int a = 1, b = 2;
    return getCode(a) + b;
}

$ gcc -c -g test.c

$ objdump -Sd ./test.o

00000000 <main>:
int get_int(int c);
int main(void) { /* here, the prologue creates the frame for main */
   0:   8d 4c 24 04             lea    0x4(%esp),%ecx
   4:   83 e4 f0                and    $0xfffffff0,%esp
   7:   ff 71 fc                pushl  -0x4(%ecx)
   a:   55                      push   %ebp
   b:   89 e5                   mov    %esp,%ebp
   d:   51                      push   %ecx
   e:   83 ec 14                sub    $0x14,%esp
    int a = 1, b = 2; /* setting up space for locals */
  11:   c7 45 f4 01 00 00 00    movl   $0x1,-0xc(%ebp)
  18:   c7 45 f8 02 00 00 00    movl   $0x2,-0x8(%ebp)
    return getCode(a) + b;
  1f:   8b 45 f4                mov    -0xc(%ebp),%eax
  22:   89 04 24                mov    %eax,(%esp)
  25:   e8 fc ff ff ff          call   26 <main+0x26>
  2a:   03 45 f8                add    -0x8(%ebp),%eax
} /* the epilogue runs, returning to the previous frame */
  2d:   83 c4 14                add    $0x14,%esp
  30:   59                      pop    %ecx
  31:   5d                      pop    %ebp
  32:   8d 61 fc                lea    -0x4(%ecx),%esp
  35:   c3                      ret

答案 1 :(得分:10)

我不确定你的意思是“C指令”,也许是陈述或行?当然,由于许多因素,这会有很大差异,但在看了我自己的一些示例程序后,其中很多都接近2-1标记(每个LOC 2个汇编指令),我不知道这是什么意味着什么或它如何有用。

您可以通过要求编译器仅生成程序集(例如gcc -S)或在已编译的可执行文件上使用反汇编程序来自行解决任何特定程序和实现组合(但您需要无论如何要比较它的源代码。)

修改

根据您对要完成的内容的澄清(了解现代处理器可以在一秒内执行多少行代码)来扩展这一点:

虽然现代处理器可能以每秒30亿个周期运行,但这并不意味着它每秒可以执行30亿个指令。以下是一些需要考虑的事项:

  • 许多指令需要多个周期才能执行(除法或浮点运算可能需要几十个周期才能执行)。
  • 大多数程序花费大部分时间等待内存访问,磁盘访问等等。
  • 许多其他因素,包括操作系统开销(调度,系统调用等)也是限制因素。

但总的来说,处理器非常快,可以在很短的时间内完成令人惊叹的事情。

答案 2 :(得分:4)

变化很大!如果他们试图提供粗略的转换,我不相信任何人。

i++;等语句可以转换为单个INC AX

在为呼叫设置堆栈时,包含许多参数的函数调用语句可以是几十条指令。

然后在其中添加编译器优化,它将以不同于您编写代码的方式汇编代码,从而消除指令。

此外,某些指令在机器字边界上运行得更好,因此NOP将在整个代码中使用。{/ p>

答案 3 :(得分:3)

我认为你不能从你在这里尝试做的事情中得出关于实际应用程序性能的任何有用的 。除非“不准确”意味着“在几个数量级内”。

你只是过度概括,并且你正在忽视缓存等,好像它是次要的,而它可能完全占主导地位。

如果您的应用程序足够大,可以趋向于每个位置的某些平均指令,那么它也将足够大,以便具有I / O或至少重要的RAM访问问题。

答案 4 :(得分:2)

根据您的环境,您可以使用visual studio选项:/ FAs

更多here

答案 5 :(得分:1)

我不确定这是否真的有用。当然,您必须选择架构(如您所建议的那样)。

我会做什么:采取合理规模的C程序。给gcc“-S”选项并检查自己。它将生成汇编源代码,您可以自己计算该程序的比率。

答案 6 :(得分:1)

RISC或CISC?无论如何,C中的指令是什么?

重复上述几点,除非您对所使用的代码类型非常具体,否则您根本不知道。

您可以尝试查看有关装配优化和过去30 - 40年间发生的硬件/软件干扰串扰的学术文献。这就是你要找到关于你感兴趣的东西的真实数据的地方。(虽然我警告你,你可能会看到C-> PDP数据而不是C-> IA-32数据)。

答案 7 :(得分:1)

您在其中一条评论中写道,您想知道3GHz的含义。

即使CPU的频率无关紧要。现代PC-CPU大量交错和调度指令,它们提取和预取,高速缓存存储器和指令,并且通常该高速缓存被无效并抛出到存储区。通过运行真实世界的性能基准,可以获得对处理能力的最佳解释。