我正在学习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内置非标准功能,可转换为特定的装配说明.