首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Memset结构变量单独和memset整个结构,哪个更快?

Memset结构变量单独和memset整个结构,哪个更快?
EN

Stack Overflow用户
提问于 2020-04-24 16:48:49
回答 1查看 104关注 0票数 0

假设我有一个这样的结构:

代码语言:javascript
复制
struct tmp {
    unsigned char arr1[10];
    unsigned char arr2[10];
    int  i1;
    int  i2;
    unsigned char arr3[10];
    unsigned char arr4[10];
};

其中哪一个会更快?

(1) Memset整个结构为0,然后填充成员为:

代码语言:javascript
复制
struct tmp t1;
memset(&t1, 0, sizeof(struct tmp));

t1.i1 = 10;
t1.i2 = 20;
memcpy(t1.arr1, "ab", sizeof("ab"));
// arr2, arr3 and arr4 will be filled later.

(2)记忆分离变量:

代码语言:javascript
复制
struct tmp t1;
t1.i1 = 10;
t1.i2 = 20;
memcpy(t1.arr1, "ab", sizeof("ab"));

memset(t1.arr2, 0, sizeof(t1.arr2); // will be filled later
memset(t2.arr3, 0, sizeof(t1.arr3); // will be filled later
memset(t2.arr4, 0, sizeof(t1.arr4); // will be filled later

就性能而言,多次调用memset (在结构的单独成员上)比单个调用memset (在整个结构上)更快/更慢。

EN

回答 1

Stack Overflow用户

发布于 2020-04-24 17:19:07

在没有具体系统的情况下讨论这个问题是没有实际意义的,思考这些事情也没有什么意义,除非你确实有一个性能瓶颈。我还是可以试一试。

对于一台“通用计算机”,你必须考虑:

  • Aligned access

一次访问一大块数据通常更好。在潜在未对齐的情况下,无论数据有多大,要处理的开销代码都大致相同。假设理论上这段代码中的所有访问都是未对齐的,那么1个memset调用总比3个好。

此外,我们可以假设结构的第一项是对齐的,但我们不能假设结构中的任何单个成员都是对齐的。链接器将在对齐的地址处分配结构,然后可能在其内部的任何位置添加填充以补偿未对齐。

你的struct声明时没有任何关于对齐的考虑,所以这将是一个问题-编译器将插入大量填充。

(另一方面,整个结构上的内存集也会覆盖填充字节,这是使用的code.)

  • Data缓存的一小部分开销

从上到下访问一个相邻的内存区域要比从代码中的多个位置访问它的片段要“缓存友好”得多。连续存储器的后续访问意味着计算机可以将大量数据加载到高速缓冲存储器中,而不是从随机存取存储器中取出数据,这是slower.

  • Instruction高速缓冲存储器的使用和分支预测

在这种情况下不是很相关,因为代码基本上只是进行原始拷贝,这样做会产生大量的机器指令branch-free.

  • The

这始终是一个很好的、粗略的代码速度的指示。显然,有些指令比其他指令要慢得多,但更少的指令通常意味着更快的代码。用x86_64 -O3拆分你的两个函数,然后我得到这个:

func1: movabs rax,85899345930像素xmm0,xmm0 movups XMMWORD PTR rdi+16,xmm0 mov QWORD PTR rdi+20,rax mov eax,25185 movups XMMWORD PTR rdi,xmm0 movups XMMWORD PTR rdi+32,xmm0 mov WORD PTR rdi,ax ret func2: movabs rax,85899345930 xor edx,edx xor ecx,ecx xor esi,esi mov QWORD PTR rdi+20,rax mov eax,25185 mov WORD PTR rdi,ax移位字节PTR rdi+2,0移位QWORD PTR rdi+10,0移位字PTR rdi+18,dx移位QWORD PTR rdi+28,0移位字PTR rdi+36,cx移位QWORD PTR rdi+38,0移位字PTR rdi+46,单列

这是一个很好的迹象,表明前面的代码更有效,而且它也应该对数据缓存更友好,所以如果(1)不是明显更快,我会感到惊讶。

还要注意,如果使用静态存储持续时间声明此结构,则会在调用.bss ()之前将清零操作“外包”给程序的CRT部分,并在调用main()之前执行。那么就不需要这些memset了。代价是启动速度稍慢,但总体上程序速度更快。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61404493

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档