这里是代码
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 - 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 version gcc(GCC)4.8.2 20140120(Red Hat 4.8.2-16)
服务器AWS EC2 r3.8xlarge
操作系统Amazon Linux AMI发布2014.09
这是与Why does `change_protection` hog CPU while loading a large amount of data into RAM?相关的问题
最佳答案 那么会发生什么:
>你的malloc代码.这意味着内核将页面映射到程序的空间;为此,页面甚至不必可用,它更像是“一旦你实际访问该内存就通知我”的情况.
>您的第一个循环按顺序访问页面.因此,内核经常需要将实际内存分配给以前未使用的页面.可能,AWS虚拟机管理程序正在快速从其池中提供该内存
>你再次访问这些页面 – 但是由于运气不好,160GB区域开头的页面现在可能“远”了,让它们靠近运行代码的CPU可能会很慢.请记住,您在类似于NUMA计算机的虚拟机上运行.
编辑它对SIGTERM等没有反应的事实并不令人惊讶 – 没有明确的上下文切换发生,并且在for循环中没有完成信号检查,所以你的程序无法对信号作出反应.