gpt4 book ai didi

c - 零初始化程序比 memset 快吗?

转载 作者:太空狗 更新时间:2023-10-29 15:34:45 29 4
gpt4 key购买 nike

我维护遗留 C 代码,在许多地方它们有小数组,如 int a[32]; 后跟 memset(a, 0, sizeof a);将其初始化为零。

我正在考虑将其重构为 int a[32] = {0}; 并删除 memset。

问题是:与调用 memset 相比,使用零初始值设定项是否通常会产生更快的代码?

最佳答案

TL;DR:使用初始化器 - 它永远不会比 memset() 差。

这取决于您的编译器。 它不应该比调用 memset()(因为调用 memset() 是编译器可用的一个选项)。 p>

初始化器比命令式覆盖数组更容易阅读;如果元素类型更改为全零不是您想要的类型,它也能很好地适应。


作为实验,让我们看看 GCC 对此做了什么:

#include <string.h>

int f1()
{
int a[32] = {0};
return a[31];
}

int f2()
{
int a[32];
memset(a, 0, sizeof a);
return a[31];
}

使用 gcc -S -std=c11 编译得到:

f1:
.LFB0:
.file 1 "40786375.c"
.loc 1 4 0
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $8, %rsp
.loc 1 5 0
leaq -128(%rbp), %rdx
movl $0, %eax
movl $16, %ecx
movq %rdx, %rdi
rep stosq
.loc 1 6 0
movl -4(%rbp), %eax
.loc 1 7 0
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
f2:
.LFB1:
.loc 1 10 0
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
addq $-128, %rsp
.loc 1 12 0
leaq -128(%rbp), %rax
movl $128, %edx
movl $0, %esi
movq %rax, %rdi
call memset@PLT
.loc 1 13 0
movl -4(%rbp), %eax
.loc 1 14 0
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc

显示 f1() 使用 rep stosq 作为初始化器,而 f2() 有函数调用,与 C 代码完全一样. memset() 很可能对大型数组具有更高效的矢量化实现,但对于像这样的小型数组,函数调用开销可能会抵消任何好处。

如果我们将 a 声明为 volatile,我们将看到启用优化后会发生什么 (gcc -S -std=c11 -O3 ):

f1:
.LFB4:
.cfi_startproc
subq $16, %rsp
.cfi_def_cfa_offset 24
xorl %eax, %eax
movl $16, %ecx
leaq -120(%rsp), %rdi
rep stosq
movl 4(%rsp), %eax
addq $16, %rsp
.cfi_def_cfa_offset 8
ret
.cfi_endproc
f2:
.LFB5:
.cfi_startproc
subq $16, %rsp
.cfi_def_cfa_offset 24
xorl %eax, %eax
movl $16, %ecx
leaq -120(%rsp), %rdx
movq %rdx, %rdi
rep stosq
movl 4(%rsp), %eax
addq $16, %rsp
.cfi_def_cfa_offset 8
ret
.cfi_endproc

您可以看到这两个函数现在编译为相同的代码。

关于c - 零初始化程序比 memset 快吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40786375/

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