c - 在 C 中复制两个相邻字节的最快方法是什么?

标签 c performance memory

好吧,让我们从最明显的解决方案开始:

memcpy(Ptr, (const char[]){'a', 'b'}, 2);

调用库函数的开销很大。编译器有时不会优化它,好吧,我不会依赖编译器优化,但即使 GCC 很聪明,如果我将程序移植到带有垃圾编译器的更多奇异平台,我也不想依赖它。

所以现在有一个更直接的方法:

Ptr[0] = 'a';
Ptr[1] = 'b';

它不涉及库函数的任何开销,但进行了两次不同的分配。第三,我们有一个双关语:

*(uint16_t*)Ptr = *(uint16_t*)(unsigned char[]){'a', 'b'};

如果遇到瓶颈,我应该使用哪个?在 C 中仅复制两个字节的最快方法是什么?

问候,
汉克绍里

最佳答案

您建议的方法中只有两种是正确的:

memcpy(Ptr, (const char[]){'a', 'b'}, 2);

Ptr[0] = 'a';
Ptr[1] = 'b';

在 X86 GCC 10.2 上, both compile to identical code :

mov     eax, 25185
mov     WORD PTR [something], ax

这是可能的,因为 as-if rule .

因为一个好的编译器可以找出它们是相同的,所以使用更容易在您的 cse 中编写的那个。如果要设置一个或两个字节,请使用后者,如果多个字节使用前者或使用 string 而不是复合文字数组。


你建议的第三个

*(uint16_t*)Ptr = *(uint16_t*)(unsigned char[]){'a', 'b'};

编译为same code when using x86-64 GCC 10.2 ,即在这种情况下它的行为相同。

但除此之外它还有 2-4 点未定义的行为,因为它有两次严格的别名违规和两次,加上在源和目标上可能未对齐的内存访问。未定义的行为并不意味着它不能按您的预期工作,但也不意味着它必须按您的预期工作。行为未定义。 And it can fail to work on any processor, including x86 .为什么您会如此关心编译器上的性能,以至于您编写的代码在好的编译器上无法工作?!

关于c - 在 C 中复制两个相邻字节的最快方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63169101/

相关文章:

C 管道分段故障

django - Django 的 Apache 配置性能

performance - sqlite即使索引也很难查询

c++ - c中如何获取进程ID,getpid()没有实现

c - 段错误 - strcat

c++ - C 结构中的内存对齐

javascript - 如何在单页 javascript 应用程序中发现内存泄漏?

linux - Mac 或 Linux 上的内存监控

c - 在 pthread_mutex_init 之前调用 pthread_mutex_lock 是否安全?

N行后的MySQL更新