gpt4 book ai didi

c - 在 C 中使用编写的跳转表或 switch 语句是否更快?

转载 作者:太空宇宙 更新时间:2023-11-04 05:49:52 25 4
gpt4 key购买 nike

所以,我想看看使用函数指针的跳转表与使用 switch 语句来执行许多类似这样的命令操作之间是否有任何区别。

This is the code to assembly link i made

这也是我的实际代码

enum code {
ADD,
SUB,
MUL,
DIV,
REM
};

typedef struct {
int val;
} Value;


typedef struct {
enum code ins;
int operand;
} Op;


void run(Value* arg, Op* func)
{
switch(func->ins)
{
case ADD: arg->val += func->operand; break;
case SUB: arg->val -= func->operand; break;
case MUL: arg->val *= func->operand; break;
case DIV: arg->val /= func->operand; break;
case REM: arg->val %= func->operand; break;
}
}

我的问题是,根据该链接或代码中生成的程序集,在 switch 语句的情况下制作一堆小函数来完成操作,并制作一个指针数组有什么不同这些函数并使用相同的枚举调用它们?

使用 gcc x86_64 7.1

void add(Value* arg, Op* func)
{
arg->val += func->operand;
}

static void (*jmptable)(Value*, Op*)[] = {
&add
}

汇编代码粘贴:

run(Value*, Op*):
push rbp
mov rbp, rsp
mov QWORD PTR [rbp-8], rdi
mov QWORD PTR [rbp-16], rsi
mov rax, QWORD PTR [rbp-16]
mov eax, DWORD PTR [rax]
cmp eax, 4
ja .L9
mov eax, eax
mov rax, QWORD PTR .L4[0+rax*8]
jmp rax
.L4:
.quad .L3
.quad .L5
.quad .L6
.quad .L7
.quad .L8
.L3:
mov rax, QWORD PTR [rbp-8]
mov edx, DWORD PTR [rax]
mov rax, QWORD PTR [rbp-16]
mov eax, DWORD PTR [rax+4]
add edx, eax
mov rax, QWORD PTR [rbp-8]
mov DWORD PTR [rax], edx
jmp .L2
.L5:
mov rax, QWORD PTR [rbp-8]
mov edx, DWORD PTR [rax]
mov rax, QWORD PTR [rbp-16]
mov eax, DWORD PTR [rax+4]
sub edx, eax
mov rax, QWORD PTR [rbp-8]
mov DWORD PTR [rax], edx
jmp .L2
.L6:
mov rax, QWORD PTR [rbp-8]
mov edx, DWORD PTR [rax]
mov rax, QWORD PTR [rbp-16]
mov eax, DWORD PTR [rax+4]
imul edx, eax
mov rax, QWORD PTR [rbp-8]
mov DWORD PTR [rax], edx
jmp .L2
.L7:
mov rax, QWORD PTR [rbp-8]
mov eax, DWORD PTR [rax]
mov rdx, QWORD PTR [rbp-16]
mov esi, DWORD PTR [rdx+4]
cdq
idiv esi
mov edx, eax
mov rax, QWORD PTR [rbp-8]
mov DWORD PTR [rax], edx
jmp .L2
.L8:
mov rax, QWORD PTR [rbp-8]
mov eax, DWORD PTR [rax]
mov rdx, QWORD PTR [rbp-16]
mov ecx, DWORD PTR [rdx+4]
cdq
idiv ecx
mov rax, QWORD PTR [rbp-8]
mov DWORD PTR [rax], edx
nop
.L2:
.L9:
nop
pop rbp
ret

最佳答案

所有这些问题的一个包罗万象的答案:你应该衡量。

但实际上,我赌的是 switch 版本。函数调用有开销(并且在这种情况下它们几乎不能内联),您可以使用标签作为值消除开销,这是一个常见的编译器扩展*,但您应该真正尝试所有选项并衡量如果这段代码的性能对您很重要。

否则,请使用对您来说最方便的任何方式。


*a switch 可能会生成一个跳转表,该跳转表等同于您可以从标签作为值 组成的内容,但它可以根据特定情况值在不同的实现之间切换以及他们的人数

关于c - 在 C 中使用编写的跳转表或 switch 语句是否更快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45068614/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com