结构赋值的 gcc 优化

Posted

技术标签:

【中文标题】结构赋值的 gcc 优化【英文标题】:gcc optimization of struct assignment 【发布时间】:2019-04-11 05:57:47 【问题描述】:

这是我的示例代码:

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 一样。

在 gcc 5.4.0 生成时,fun2 真的比fun1 快吗?

我有一些旧项目,它们是使用更旧版本的 gcc (4.x) 编译的,我发现了许多与我的示例类似的代码。如果我想进行优化,将fun1 更改为fun2 是不是一个好主意?我暂时无法更新 gcc。

【问题讨论】:

【参考方案1】:

假设这些程序在现代 CPU 架构上运行,差异将在纳秒级。

除非您的代码主要由这些分配组成,并且您确实需要挤出一点点性能,否则我会将它与fun1 保持相同以提高可读性和可维护性。

【讨论】:

以上是关于结构赋值的 gcc 优化的主要内容,如果未能解决你的问题,请参考以下文章

为啥 GCC 不优化结构?

GCC 不优化未初始化的静态常量的结构副本

结构体赋值

GCC编译器中的性能优化

C++学习(三四八)CLang GCC

gcc/clang 在基本结构的后填充中布置派生结构的字段[重复]