gcc - 结构赋值的 gcc 优化
问题描述
这是我的示例代码:
struct AAA {
union{
struct{
int a;
int b;
};
long A;
};
union{
struct{
short c;
char d;
char e;
};
int B;
};
} __attribute__((packed));
void fun1(struct AAA *aaa){
aaa->a = 1;
aaa->b = 2;
aaa->c = 3;
aaa->d = 4;
aaa->e = 5;
}
void fun2(struct AAA *aaa){
aaa->A = (2L<<32)+1;
aaa->B = (5 << 24) + (4<<16) + 3;
}
当我使用 gcc 5.4.0 将其编译为 asm 代码时,我得到:
fun1:
.LFB0:
.cfi_startproc
movl $3, %eax
movl $1, (%rdi)
movl $2, 4(%rdi)
movw %ax, 8(%rdi)
movb $4, 10(%rdi)
movb $5, 11(%rdi)
ret
.cfi_endproc
.LFE0:
.size fun1, .-fun1
.section .text.unlikely
.LCOLDE0:
.text
.LHOTE0:
.section .text.unlikely
.LCOLDB1:
.text
.LHOTB1:
.p2align 4,,15
.globl fun2
.type fun2, @function
fun2:
.LFB1:
.cfi_startproc
movabsq $8589934593, %rax
movl $84148227, 8(%rdi)
movq %rax, (%rdi)
ret
.cfi_endproc
当我用 gcc 7.3.0 编译它时,我得到了
fun1:
.LFB0:
.cfi_startproc
movabsq $8589934593, %rax
movl $84148227, 8(%rdi)
movq %rax, (%rdi)
ret
.cfi_endproc
.LFE0:
.size fun1, .-fun1
.p2align 4,,15
.globl fun2
.type fun2, @function
fun2:
.LFB1:
.cfi_startproc
movabsq $8589934593, %rax
movl $84148227, 8(%rdi)
movq %rax, (%rdi)
ret
.cfi_endproc
两者都使用 -O3 选项。区别很明显。较新版本的 gcc 优化fun1
就像fun2
.
真的fun2
比fun1
gcc 5.4.0 生成时快吗?
我有一些旧项目,它们是使用更旧版本的 gcc (4.x) 编译的,我发现了许多类似的代码,例如我的示例。如果我想做优化,改成 是个好主意fun1
吗fun2
?我暂时无法更新 gcc。
解决方案
假设这些程序在现代 CPU 架构上运行,差异将在纳秒的测量中。
除非您的代码主要由这些分配组成,并且您确实需要挤出一点点性能,否则我会保持相同fun1
以提高可读性和可维护性。
推荐阅读
- sql - SQL 数据流上的运行平均值
- android - supportFragmentManager 不适用于 kotlin
- javascript - 使用带有状态的打字稿?当用户输入字符串以外的内容时,我如何进行类型检查,我目前对打字稿很陌生
- java - 如何等待多个 Flux 和 Mono 发布者同时完成
- python - 桌面上路径的python字符串
- javascript - 输入字段值在一个区域工作而不在另一个区域工作
- typescript - 从导出的 Typescript 命名空间导入接口
- go - 反转二叉树:如何正确交换整个左树和右树
- swift - 如何指定哪个构建目标包含特定的 swift 包依赖项?
- clojure - 十进制转二进制 Clojure