本节介绍控制物理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)。
在这里创建一个新的cpu分配组groupa。与其他cgroup同样在挂载的cgroup下创建新目录groupa,作为分组groupa。
编辑新创建分组groupa的cpuset,修改cpu分配情况。这里以仅将cpu0分配给分组groupa的情况为例进行说明。在分组groupa下的特殊文件cpuset.cpus内写入要分配的cpu编号,使用下列命令,来控制分组的cpuset。
到这一步,就完成了仅使用cpu0作为groupa的cpu分配的设置。
接下来,在这个分组groupa中添加进程。这里将当前shell添加到groupa中。使用下列命令,将pid(
$$
表示shell本身的pid)写入groupa下的task文件。
此后由当前shell启动的进程全部在这个groupa下,使用的cpu仅限于0号cpu。
现在确认所使用的cpu数量是否受限,以及产生的效果如何。本节显示的是以fedora 12为例的情况。
本示例中使用的fedora 12内核如下。
如果使用cpuset改变所使用的cpu数量会怎么样?比较内核的编译时间。
首先准备好要进行比较的编译。为了避免磁盘性能的影响,首先创建内存文件系统tmpfs,并在其中配置源文件。创建目录/tmp/build,挂载 tmpfs,命令如下所示。
本次测量的是内核源代码每次在创建的tmpfs下解压缩tarball时,使用默认config所花费的内核编译时间。使用的一系列命令行如下。
首先测量linux 2.6.33的编译时间。
将cgroup挂载到/cgroup,创建分组groupa。
接下来看一下向分组groupa分配两个cpu时的结果。
编译时间如下。
然后将cpu缩减到只有0号cpu。
可以看到,cpu数量变为1,实际花费的时间(real)增加。
下面以对虚拟化(kvm)进程所使用的cpu进行限制的情况为例,看一下将分配给kvm进程的cpu固定,并确保主机操作系统能够一直使用cpu后,是否能够减少虚拟化的影响。
这个示例同样使用fedora 12。
首先使用kvm,启动两个客户端操作系统。然后,在客户端操作系统中循环进行内核编译,加大cpu负载。
在解压缩linux 2.6.33源代码的目录下,无限循环执行make clean和make命令,增加客户端操作系统的cpu负载。
在这种情况下计算主机操作系统上的内核编译时间。同前例一样,需要创建tmpfs,消除磁盘性能的影响后再进行测量。计算结果如下。
然后,将kvm的qemu-kvm进程可以使用的cpu设置为只有0号cpu。
将启动中的qemu-kvm移动到kvm分组。
另外,ksmd(参考hack #36)也使用cpu,因此这里也将其加入kvm分组。
现在,主机操作系统的内核编译时间就变成如下所示。
可以发现,内核编译所花费的实际时间减少了接近30秒。
这是因为虚拟化的kvm进程只在cpu0上运行,在主机操作系统上就可以使用100%的cpu。
小结
本节介绍了使用linux中的cgroup的cpuset。通过使用这个功能,就可以限制特定进程所使用的cpu。从另一个角度来看,通过固定使用的cpu,还可以提高缓存的利用效率和性能。
—hiroshi shimamoto