汇编代码的长度可以指示执行速度吗?

Lan*_*nti 1 c assembly clang

我正在学习C,请考虑以下代码片段:

#include <stdio.h>

int main(void) {
  int fahr;
  float calc;

  for (fahr = 300; fahr >= 0; fahr = fahr - 20) {
    calc = (5.0 / 9.0) * (fahr - 32);
    printf("%3d %6.1f\n", fahr, calc);
  }

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

这是将Celsius到华氏温度转换表从300打印到0.我用以下代码编译:

$ clang -std=c11 -Wall -g -O3 -march=native main.c -o main
Run Code Online (Sandbox Code Playgroud)

我还使用此命令生成汇编代码:

$ clang -std=c11 -Wall -S -masm=intel -O3 -march=native main.c -o main
Run Code Online (Sandbox Code Playgroud)

哪个生成1.26kb文件和71行.

我稍微编辑了代码并将逻辑移到另一个函数中,该函数在main()中被初始化:

#include <stdio.h>

void foo(void) {
  int fahr;
  float calc;

  for (fahr = 300; fahr >= 0; fahr = fahr - 20) {
    calc = (5.0 / 9.0) * (fahr - 32);
    printf("%3d %6.1f\n", fahr, calc);
  }
}

int main(void) {
  foo();
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

这将生成2.33kb汇编代码,128行.

运行两个程序time ./main我发现执行速度没有区别.

我的问题是,尝试通过汇编代码的长度来优化您的C程序是否重要?

Mar*_*oom 12

看来你正在比较.SGCC生成的文件的大小,因为这显然毫无意义,我只是假装你面对二进制大小为2,GCC生成的代码片段.

虽然在所有其他条件相同的情况下,较短的代码大小可能会提高速度(由于更高的代码密度),但通常x86 CPU足够复杂,需要在代码大小优化和代码速度优化之间进行解耦.

特别是如果你瞄准代码速度,你应该优化代码速度.有时这需要选择最短的片段,有时则不需要.

考虑编译器优化的经典示例,乘以2的幂:

int i = 4;
i = i * 8;
Run Code Online (Sandbox Code Playgroud)

这可能被严重翻译为:

;NO optimizations at all

mov eax, 4        ;i = 4        B804000000       0-1 clocks
imul eax, 8       ;i = i * 8    6BC009           3 clocks
                  ;eax = i      8 bytes total    3-4 clocks total

;Slightly optimized
;4*8 gives no sign issue, we can use shl

mov eax, 4        ;i = 4        B804000000       0-1 clocks
shl eax, 3        ;i = i * 8    C1E003           1 clock
                  ;eax = i      8 bytes total    1-2 clocks total
Run Code Online (Sandbox Code Playgroud)

两个片段具有相同的代码长度,但第二个片段的速度几乎是两倍.

这是一个非常基本的示例1,其中甚至不需要考虑微架构.

另一个更微妙的例子如下,取自Agner Fog关于部分登记档位2的讨论:

;Version A                        Version B

mov al, byte ptr [mem8]           movzx ebx, byte ptr [mem8]
mov ebx, eax                      and eax, 0ffffff00h
                                  or ebx, eax

;7 bytes                           14 bytes
Run Code Online (Sandbox Code Playgroud)

两个版本都给出相同的结果,但版本B版本A快5-6个时钟,尽管前者的版本是后者的两倍.


答案是否定的,代码大小不够; 虽然它可能是一个打破平局.

如果您真的对优化装配感兴趣,您将享受以下两个读数:

第一个链接还有一个优化C和C++代码的手册.


如果用C语言编写,请记住最有影响的优化是1)如何表示/存储数据,即数据结构2)如何处理数据,即算法.
有宏优化.

考虑到生成的程序集正在转向微优化,最有用的工具是1)智能编译器2)一组很好的内在函数3.


1在实践中如此简单地进行优化.
2现在可能有点过时,但它有助于达到目的.
3内置非标准功能,可转换为特定的装配说明.