首页 > 解决方案 > 结构赋值的 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.

真的fun2fun1gcc 5.4.0 生成时快吗?

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

标签: gccoptimization

解决方案


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

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


推荐阅读