性能提升之CPU

这篇文章来自同事加哥们阿福同学以前写在csdn博客里的,因为我经常需要搜索,这里就直接copy过来了,由于他就坐我旁边,肯定不会涉及到侵权问题,来瓶雪花就打发了,不过他csdn已经没维护了,有兴趣的可以前往他个人主页:http://www.hiyoufu.com/

我们知道现在服务器都是多核, 最新的intel Sandybridge是NUMA IO结构, 以网卡为例, 也就是说PCI插槽并不像westmere一样, 通过一个bridge连接到cpu上, 目前SNB是直接pci链接到cpu上。

有时候我们测试performance的时候会看到性能忽高忽低的现象, 原因比较难找, 一头雾水, 下面我根据自己的实际经验列出下面几个cpu对性能的影响:

多核并行编程cpu的亲和性以及frequence对性能的影响可能比较大, 如果设置不好cpu的affinity, 通过跨QPI 来访问另一个CPU上的内存, 那么性能差距经过测试, 会有10倍的差距(两个10G网口收包, 平均包长256, 最坏的情况2.5Gbps, 最好的情况19.8Gbps, 64byte小包在L4 上能达到16.5Gbps)。

首先我们保证在硬件cpu上不受影响,在这里暂时不考虑cache一致性的问题 :

1.保证cpu运行最高的频率, 目前默认基本都是ondemand, 也就是根据cpu的空闲程度来自动调节频率, C state, 为了保证CPU 运行在P状态, 也就是performance状态(当然耗电会大一些) , 可以通过下面的脚本做如下设置:

  1. #!/bin/bash
  2. for f in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
  3. do
  4.     echo performance > $f
  5. done
  6. exit 0

这样可以保证cpu运行在最佳状态, 通过lscpu可以看出, cpu的频率已经是最高的频率了。

2.cpu的set affinity或者taskset仅仅对用户层的程序有用, 陷入内核后就无法保证当前线程运行在哪个cpu上了, 我们要保证在内核上分配内存时通过vmalloc_node来指定正确的socket。

3.linux 内核目前提供了offline cpu的功能, 当然cpu core 0目前是无法进行offline的(我认识的一个内核大师正在做cpu 0 offline的功能, 估计很快内核会支持), 所以我们为了排除cpu NUMA的影响, 可以将socket 1上的所有的core进行logical offline, 这样内核就看不到socket 1上的所有的cpu core了, 内存分配会自动到node 0上。

我们运行下面命令:

cd /sys/devices/system/cpu/

ls

cd online

可以看到online的cpu的编号,就是说内核可以使用的cpu编号。

我们以offline cpu11 为例, 这里的编号是core的编号

cd cpu11

cat online

echo 0 > online

这样就可以offline cpu11了, 我们在top命令或者别的一些观察cpu的命令中就无法看到cpu11了, 这里面的具体实现机制比较复杂, 感兴趣的可以去看内核源代码。

发表评论