c++ - 奇怪的行为 : memcpy faster 1x when src is not set value

标签 c++ memcpy

GCC 版本:gcc 4.8.5

copt: -std=c++11 -O3

SIZE = 50 * 1024 * 1024

第一段代码:

int main() {
  char* src = new char[SIZE];
  char* dst = new char[SIZE];

  memset(dst, 'a', SIZE);

  for (size_t i = 0; i < 5; ++i) {
    size_t start = now();
    memcpy(dst, src, SIZE);
    cout << "timer:" << now() - start << "ms" << endl;
  }
  return 0;
}

输出:

timer:5ms

timer:4ms

timer:5ms

timer:5ms

timer:4ms

第二段代码:

int main() {
  char* src = new char[SIZE];
  char* dst = new char[SIZE];

  memset(src, 'a', SIZE);
  memset(dst, 'a', SIZE);

  for (size_t i = 0; i < 5; ++i) {
    size_t start = now();
    memcpy(dst, src, SIZE);
    cout << "timer:" << now() - start << "ms" << endl;
  }
  return 0;
}

输出:

timer:9ms

timer:8ms

timer:8ms

timer:8ms

timer:8ms

第三段代码:

int main() {
  char* src = new char[SIZE];
  char* dst = new char[SIZE];

  for (size_t i = 0; i < 5; ++i) {
    size_t start = now();
    memcpy(dst, src, SIZE);
    cout << "timer:" << now() - start << "ms" << endl;
  }
  return 0;
}

输出:

timer:22ms

timer:4ms

timer:5ms

timer:5ms

timer:5ms

总结:

  1. 比较第一和第三种情况:第三种情况的第一轮慢是因为轻微的页面错误。

问题:

  1. 为什么在第一种情况下,memcpy src 不会触发任何小页面错误?

  2. 为什么在第二种情况下,比第一种情况慢 1 倍。操作系统有什么优化吗?

最佳答案

Memcpy 受外部存储器吞吐量的限制;看起来操作系统能够虚拟地将内存分配到页表中并执行 Copy-on-write .这可以解释这两种现象:只有一个物理内存块保留给未修改的 src,在情况 2 和 3 中,它位于最快的缓存中。如果一个所有的内存访问都会上下移动到外部存储器。案例 2 的运行 1 中的 5 倍速度损失是由于虚拟分配的 src 在写入时被复制到唯一的物理页面。

连续 N 次对初始 memset 计时应该可以证实假设。

The copy-on-write technique can be extended to support efficient memory allocation by having a page of physical memory filled with zeros. When the memory is allocated, all the pages returned refer to the page of zeros and are all marked copy-on-write. This way, physical memory is not allocated for the process until data is written, allowing processes to reserve more virtual memory than physical memory and use memory sparsely, at the risk of running out of virtual address space.

关于c++ - 奇怪的行为 : memcpy faster 1x when src is not set value,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47027666/

相关文章:

c++ - 对象的大小与没有指针的类的大小不同

c++ - 为什么 ShellExecute 找不到文件?

c++ - 我的仿射变换发生了一些奇怪的事情

c++ - Python 和 C++ 中的函数式编程

C++类成员和内存位置

c++ - 如何读取 C++ 中 system() 调用的结果?

c++ - 在没有 CRT、memcpy 和 memset 内部函数的情况下构建时出现链接错误

c++ - 'memcpy' 未在此范围内定义

复制包含长整数的字符串

c - memcpy 额外的起始字符