首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >绩效: memset

绩效: memset
EN

Stack Overflow用户
提问于 2014-05-18 14:49:06
回答 2查看 4.6K关注 0票数 13

我有一个简单的C代码来完成这个任务(伪代码):

代码语言:javascript
运行
复制
#define N 100000000
int *DataSrc = (int *) malloc(N);
int *DataDest = (int *) malloc(N);
memset(DataSrc, 0, N);
for (int i = 0 ; i < 4 ; i++) {
    StartTimer();
    memcpy(DataDest, DataSrc, N);
    StopTimer();
}
printf("%d\n", DataDest[RandomInteger]);

我的个人电脑:IntelCorei7-3930,4x4GB DDR3 1600内存运行RedHat 6.1 64位.

第一个memcpy()以1.9GB/秒的速度出现,而接下来的三个为6.2GB/s。缓冲区大小(N)太大,不可能由缓存效应造成。所以,我的第一个问题是:

  • 为什么第一个memcpy()要慢得多呢?也许malloc()在使用它之前不会完全分配内存?

如果消除了memset(),那么第一个memcpy()以1.5GB/秒的速度运行,而接下来的三个memcpy()以11.8GB/秒的速度运行。快2倍了。我的第二个问题是:

  • 如果我不打电话给memcpy(),为什么memset()快2x?
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-05-18 15:32:35

正如其他人已经指出的,Linux使用乐观内存分配策略

第一个和接下来的memcpy之间的区别是DataDest的初始化。

正如您已经看到的,当您消除memset(DataSrc, 0, N)时,第一个memcpy甚至更慢,因为源的页面也必须被分配。当您同时初始化DataSrcDataDest时,例如。

代码语言:javascript
运行
复制
memset(DataSrc, 0, N);
memset(DataDest, 0, N);

所有memcpy都将以大致相同的速度运行。

对于第二个问题:当您使用memset初始化分配的内存时,所有页面都将被连续排列。另一方面,当您复制时分配内存时,源页和目标页将被交错分配,这可能会造成差异。

票数 11
EN

Stack Overflow用户

发布于 2014-05-18 14:52:26

这很可能是由于VM子系统中的延迟分配造成的。通常,当您分配大量内存时,只有第一个N页实际被分配并连接到物理内存中。当您访问这些第一个N页之后,就会生成页面错误,并在“按需”的基础上分配和连接更多的页面。

至于问题的第二部分,我相信有些VM实现实际上跟踪零页并专门处理它们。尝试将DataSrc初始化为实际(例如随机)值,并重复测试。

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

https://stackoverflow.com/questions/23723215

复制
相关文章

相似问题

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