在多核体系结构上,cpu affinity的合理运用对并行程序运行性能的影响举足轻重,为了避免资源竞争,会将不同的进程或者线程绑在不同的核上执行,充分发挥多核并行的性能优势
在linux操作系统里,可以通过shell里taskset命令直接对程序运行或者正在运行的进程的pid进行绑核,只需要lscpu或者/proc/cpuinfo得到cpu核的NUMA结构以及编号,进行合理的设置cpu affinity
Perl里设置CPU Affinity可以通过模块Sys::CpuAffinity来实现,具体可以通过CPAN搜索,它给了一个具体的例子:
use Sys::CpuAffinity; $num_cpus = Sys::CpuAffinity::getNumCpus(); $mask = 1 | 4 | 8 | 16; # prefer CPU's # 0, 2, 3, 4 $success = Sys::CpuAffinity::setAffinity($pid,$mask); $success = Sys::CpuAffinity::setAffinity($pid, \@preferred_cpus); $mask = Sys::CpuAffinity::getAffinity($pid); @cpus = Sys::CpuAffinity::getAffinity($pid);
这段代码根据变量命名以及注释基本也能明白意思,实际上绑的是0,2,3,4号核,最关键的就是一个Sys::CpuAffinity::setAffinity,它后面带有两个参数,第一个参数是你需要绑核的进程pid,第二个参数是程序需要绑的core id或者core id的列表(如果不止运行在一个核上),运用起来十分简洁和直观
更直观的比如想在1,2号核上执行一个管道命令$cmd并得到命令的输出结果只需要:
use Sys::CpuAffinity; $pid = open PRINTER, "$cmd |; $Sys::CpuAffinity::setAffinity($pid, [1,2]); //$这样cmd这条命令的执行就绑到了1和2号核上,不会运行到其它核上 while(<PRINTER>){ }//接下来可能对输出结果做文本处理,等
不过Cpu Affinity的设置到底是否值得或者说到底会不会提高性能,这取决于具体程序本身以及实现方法,本人曾经一个多进程PERL程序,通过上面绑核之后,性能反而下降了,说明程序本身写得不好或者是绑核不合理,绑了反而还不如系统自己来调度性能好