- HACK#11 cpuset
- mount-o cpuset-t cgroup cgroup/cgroup
- mkdir/cgroup/GroupA
- echo 0>/cgroup/GroupA/cpuset.cpus
- echo$$>/cgroup/GroupA/task
- uname-a
- mkdir/tmp/build
- mount-t tmpfs none/tmp/build
- cd/tmp/build/
- tar jxf/ext4data/kernel/linux-2.6.33.tar.bz2
- cd linux-2.6.33/
- make defconfg
- time make-j 2
- mount-o cpuset-t cgroup cgroup/cgroup
- mkdir/cgroup/GroupA
- echo"0-1">/cgroup/GroupA/cpuset.cpus
- echo 0>/cgroup/GroupA/cpuset.mems mems默认为空,因此需要填入值
- echo$$>/cgroup/GroupA/tasks
- time make-j 2
- echo 0>/cgroup/GroupA/cpuset.cpus
- echo 0>/cgroup/GroupA/cpuset.mems
- echo$$>/cgroup/GroupA/tasks
- mount-t tmpfs none/tmp/build
- cd/tmp/build/
- tar jxf/ext4data/kernel/linux-2.6.33.tar.bz2
- cd linux-2.6.33/
- make defconfg
- time make-j 2
- time make-j 2
- mount-o cpuset-t cgroup cgroup/cgroup
- mkdir/cgroup/kvm
- echo 0>/cgroup/kvm/cpuset.meme将kvm分组的cpuset设为只有0
- echo 0>/cgroup/kvm/cpuset.cpus
- ps x|grep qemu
- for i in'\ls/proc/2495/task/';do echo$i>/cgroup/kvm/tasks;done
- for i in'\ls/proc/2628/task/';do echo$i>/cgroup/kvm/tasks;done
- ps ux|grep ksmd
- echo 35>/cgroup/kvm/tasks
- time make-j 2
HACK#11 cpuset
本节介绍控制物理CPU分配的cpuset。
cpuset是Linux控制组(Cgroup)之一,其功能是指定特定进程或线程所使用的CPU组。另外,除CPU以外,同样还能指定内存节点的分配。
以前的内核具有CPU affinity功能,该功能将线程分配给特定CPU。现在的内核中虽然也有affinity(taskset命令),但推荐使用cpuset。
用法
使用cpuset前,必须通过内核config启用cpuset功能。
CONFIG_CPUSETS=y
最近的发布版在标准中就已启用。cpuset就是作为Cgroup提供的一个功能。因此,使用cpuset时,就需要挂载Cgroup文件系统。使用下列方法启用cpuset选项,挂载Cgroup后,就可以使用cpuset(参考Hack#7)。
mount-o cpuset-t cgroup cgroup/cgroup
在这里创建一个新的CPU分配组GroupA。与其他Cgroup同样在挂载的Cgroup下创建新目录GroupA,作为分组GroupA。
mkdir/cgroup/GroupA
编辑新创建分组GroupA的cpuset,修改CPU分配情况。这里以仅将CPU0分配给分组GroupA的情况为例进行说明。在分组GroupA下的特殊文件cpuset.cpus内写入要分配的CPU编号,使用下列命令,来控制分组的cpuset。
echo 0>/cgroup/GroupA/cpuset.cpus
到这一步,就完成了仅使用CPU0作为GroupA的CPU分配的设置。
接下来,在这个分组GroupA中添加进程。这里将当前shell添加到GroupA中。使用下列命令,将PID($$表示shell本身的PID)写入GroupA下的task文件。
echo$$>/cgroup/GroupA/task
此后由当前shell启动的进程全部在这个GroupA下,使用的CPU仅限于0号CPU。
现在确认所使用的CPU数量是否受限,以及产生的效果如何。本节显示的是以Fedora 12为例的情况。
本示例中使用的Fedora 12内核如下。
uname-a
Linux fedora12 2.6.31.12-174.2.22.fc12.x86_64#1 SMP Fri Feb 19 18:55:03 UTC 2010
x86_64 x86_64 x86_64 GNU/Linux
如果使用cpuset改变所使用的CPU数量会怎么样?比较内核的编译时间。
首先准备好要进行比较的编译。为了避免磁盘性能的影响,首先创建内存文件系统tmpfs,并在其中配置源文件。创建目录/tmp/build,挂载tmpfs,命令如下所示。
mkdir/tmp/build
mount-t tmpfs none/tmp/build
本次测量的是内核源代码每次在创建的tmpfs下解压缩tarball时,使用默认config所花费的内核编译时间。使用的一系列命令行如下。
cd/tmp/build/
tar jxf/ext4data/kernel/linux-2.6.33.tar.bz2
cd linux-2.6.33/
make defconfg
time make-j 2
首先测量Linux 2.6.33的编译时间。
将Cgroup挂载到/cgroup,创建分组GroupA。
mount-o cpuset-t cgroup cgroup/cgroup
mkdir/cgroup/GroupA
接下来看一下向分组GroupA分配两个CPU时的结果。
echo"0-1">/cgroup/GroupA/cpuset.cpus
echo 0>/cgroup/GroupA/cpuset.mems mems默认为空,因此需要填入值
echo$$>/cgroup/GroupA/tasks
编译时间如下。
time make-j 2
real 4m55.568s
user 2m42.066s
sys 5m4.575s
然后将CPU缩减到只有0号CPU。
echo 0>/cgroup/GroupA/cpuset.cpus
echo 0>/cgroup/GroupA/cpuset.mems
echo$$>/cgroup/GroupA/tasks
mount-t tmpfs none/tmp/build
cd/tmp/build/
tar jxf/ext4data/kernel/linux-2.6.33.tar.bz2
cd linux-2.6.33/
make defconfg
time make-j 2
real 7m44.491s
user 2m47.319s
sys 4m56.737s
可以看到,CPU数量变为1,实际花费的时间(real)增加。
下面以对虚拟化(KVM)进程所使用的CPU进行限制的情况为例,看一下将分配给KVM进程的CPU固定,并确保主机操作系统能够一直使用CPU后,是否能够减少虚拟化的影响。
这个示例同样使用Fedora 12。
首先使用KVM,启动两个客户端操作系统。然后,在客户端操作系统中循环进行内核编译,加大CPU负载。
在解压缩Linux 2.6.33源代码的目录下,无限循环执行make clean和make命令,增加客户端操作系统的CPU负载。
hshimamoto@ubuntu:~/kernel/linux-2.6.33$while:;do make clean;time make;done
hshimamoto@opensuse:~/kernel/linux-2.6.33>while:;do make clean;time make;done
在这种情况下计算主机操作系统上的内核编译时间。同前例一样,需要创建tmpfs,消除磁盘性能的影响后再进行测量。计算结果如下。
time make-j 2
real 8m20.468s
user 2m45.890s
sys 4m51.091s
然后,将KVM的qemu-kvm进程可以使用的CPU设置为只有0号CPU。
mount-o cpuset-t cgroup cgroup/cgroup
mkdir/cgroup/kvm
echo 0>/cgroup/kvm/cpuset.meme将kvm分组的cpuset设为只有0
echo 0>/cgroup/kvm/cpuset.cpus
将启动中的qemu-kvm移动到kvm分组。
ps x|grep qemu
2495 pts/2 Sl+238:37 qemu-kvm
2628 pts/3 Sl+255:33 qemu-kvm
for i in'\ls/proc/2495/task/';do echo$i>/cgroup/kvm/tasks;done
for i in'\ls/proc/2628/task/';do echo$i>/cgroup/kvm/tasks;done
另外,ksmd(参考Hack#36)也使用CPU,因此这里也将其加入kvm分组。
ps ux|grep ksmd
root 35 2.2 0.0 0 0?SN Mar23 119:42[ksmd]
echo 35>/cgroup/kvm/tasks
现在,主机操作系统的内核编译时间就变成如下所示。
time make-j 2
real 7m55.081s
user 2m43.303s
sys 5m12.039s
可以发现,内核编译所花费的实际时间减少了接近30秒。
这是因为虚拟化的KVM进程只在CPU0上运行,在主机操作系统上就可以使用100%的CPU。