为什么更新大数组使“change_protection”内核调用占主导地位的CPU?

时间:2015-10-21 10:51:50

标签: c linux gcc

这里是代码gcc test.c -std=c99

#include <stdio.h>
#include <stdlib.h>
void main() {
        size_t size = (long) 40 * 1024 * 1024 * 1024;
        int* buffer = malloc(size * sizeof(int));
        for (size_t i = 0; i < size; i++) {
                buffer[i] = 1;
        }
        printf("hello\n");
        for (size_t i = 0; i < size; i++) {
                buffer[i] = 2;
        }
        printf("hello\n");
}

160G ram一次性分配,并遍历两次

第一个循环愉快地运行

然而程序有点卡在第二个循环中

perf top显示此

Samples: 7M of event 'cpu-clock', Event count (approx.): 14127849698
 74.95%  [kernel]             [k] change_protection
 23.52%  [kernel]             [k] vm_normal_page
  0.40%  [kernel]             [k] _raw_spin_lock
  0.34%  [kernel]             [k] _raw_spin_unlock

top显示此

top - 10:52:36 up 55 min,  4 users,  load average: 1.16, 1.18, 1.04
Tasks: 240 total,   2 running, 238 sleeping,   0 stopped,   0 zombie
Cpu(s):  0.0%us,  3.1%sy,  0.0%ni, 96.9%id,  0.0%wa,  0.0%hi,  0.0%s
Mem:  251913536k total, 170229472k used, 81684064k free,    27820k b
Swap:        0k total,        0k used,        0k free,   352816k cac

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
12825 dapeng    20   0  160g 160g  376 R 100.0 66.6  30:38.55 a.out

现在最好的部分是该程序不再回答kill命令

gcc版本gcc (GCC) 4.8.2 20140120 (Red Hat 4.8.2-16)

服务器AWS EC2 r3.8xlarge

操作系统Amazon Linux AMI release 2014.09

这是与Why does `change_protection` hog CPU while loading a large amount of data into RAM?

相关的问题

1 个答案:

答案 0 :(得分:2)

所以会发生什么:

  1. malloc代码。这意味着内核将页面映射到程序的空间;为此,页面甚至不必可用,它更像是“一旦你实际访问该内存就通知我”的情况。
  2. 您的第一个循环按顺序访问页面。因此,内核经常需要将实际内存分配给以前未使用的页面。可能是,AWS虚拟机管理程序正在快速提供其池中的内存
  3. 你再次访问这些页面 - 但是由于运气不好,160GB区域开头的页面现在可能“远”了,让它们靠近运行代码的CPU可能是慢。请记住,您正在使用类似NUMA计算机的 VM 上运行。
  4. 编辑它对SIGTERM等没有反应这一事实并不令人惊讶 - 没有明确的上下文切换发生,也没有在for中完成信号检查循环,所以你的程序无法对信号做出反应。