常量函数指针优化

问题描述 投票:0回答:1

我正在尝试使用结构内的函数指针在 C 中实现抽象接口。
类似于下面的内容

typedef int (*fn_t)(int);
typedef struct
{
    int x;
    const fn_t fnp;
}struct_t;

__attribute__((optimize("O0"))) int square(int num) 
{
    return num * num;
}

static struct_t test = {.fnp = square};

int main(void)
{
    test.x = 1;

    int fnp_ret = test.fnp(3);

    return (fnp_ret);
}

当使用 ARM-GCC-13.2.0unknown-eabi 使用 -O3 构建 godbolt 时,输出如下。

square:
        str     fp, [sp, #-4]!
        add     fp, sp, #0
        sub     sp, sp, #12
        str     r0, [fp, #-8]
        ldr     r3, [fp, #-8]
        mov     r2, r3
        mul     r2, r3, r2
        mov     r3, r2
        mov     r0, r3
        add     sp, fp, #0
        ldr     fp, [sp], #4
        bx      lr
main:
        mov     r1, #1
        ldr     r3, .L5
        mov     r0, #3
        ldr     r2, [r3, #4]
        str     r1, [r3]
        bx      r2
.L5:
        .word   .LANCHOR0

在这里可以看到,在发出的程序集中,首先在结构中找到函数指针,然后取消引用它。我觉得这很奇怪,因为函数指针是

main()
所以我希望编译器应该弄清楚它总是指向
const
函数,所以它相当于直接调用
square
函数。显然这里的情况并非如此。
在实验过程中,我注意到,如果语句 

square

被注释掉,程序集会通过直接调用

test.x = 1;
函数来执行我所期望的操作
square

我错过了什么?
有没有什么方法可以可靠地实现这一点,而无需支付上述性能损失?


c assembly gcc optimization function-pointers
1个回答
0
投票
优化O0不合适。你想要
    square: str fp, [sp, #-4]! add fp, sp, #0 sub sp, sp, #12 str r0, [fp, #-8] ldr r3, [fp, #-8] mov r2, r3 mul r2, r3, r2 mov r3, r2 mov r0, r3 add sp, fp, #0 ldr fp, [sp], #4 bx lr main: mov r0, #3 b square
  1. 这是众所周知的 gcc 优化器流程。如果您触摸结构体的任何成员,它会将整个结构体视为非 
  2. noinline
  3. 
    
  4. const
我错过了什么?有没有什么方法可以可靠地实现这一点而无需
支付上述性能损失吗?

恐怕你对此无能为力

© www.soinside.com 2019 - 2024. All rights reserved.