c语言 - 内存集的速度与直接赋值为零



请考虑下面的结构定义。

struct xyz {
char a;
void *ptr;
uint16_t num1;
uint32_t num2;
uint64_t num3;
};

我可以通过以下 3 种方式之一将此结构的实例初始化为零。

  1. 申报时

    struct xyz instance = { 0 };
    
  2. 在使用 C-99 功能声明后的某个时间。

    instance = (const struct xyz) { 0 };
    

3.memset (&instance, 0, sizeof (struct xyz));

典型的 C 结构可以由编译器添加一些填充以用于对齐目的。 所以 memset 会将填充字节初始化为零。

我的问题是:

一般来说,上述方法 1 或 2 的初始化会比方法 3 更快吗? 节省多少CPU周期并不重要,我只是好奇1和2是否比3快。

这是一个实现质量问题。

(顺便说一句,在纯理论中,实现可能有一个不是全零位字的NULL指针;在这种情况下,§3 的语义与 §1 或 §2 的语义不同;但在实践中,当今大多数常见的处理器都有一个线性虚拟地址空间,并且它们的NULL指针是所有零位的单词)

最近的 GCC 编译器(至少在通常的 x86-64 处理器上),启用了优化(例如gcc -O2)可能会产生相同(或非常相似)的机器代码(因为memset被扩展为专门编译并经常内联的__builtin_memset),因此使用memset在实践中并不慢(甚至可以因为矢量化而变得更快,例如AVX机器指令)

您可以查看生成的汇编程序代码,例如gcc -S -fverbose-asm -O2 -march=native

(在某些情况下,特别是当struct xyz有数百个字段时,编译器甚至会为您的案例 1 和 2 合成对memset的调用!

一般来说,上述方法 1 或 2 的初始化会比方法 3 更快吗?

在实践中,答案通常是否定的(因此更喜欢最易读的方法)。如果您非常关心,请对您的代码进行基准测试。

(不要忘记开发时间也要花钱;在许多情况下,你的人力时间比你可能赢得的几纳秒的CPU纳秒更有价值,而且通常不会)

最新更新