Perl Cpu Affinity

在多核体系结构上,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程序,通过上面绑核之后,性能反而下降了,说明程序本身写得不好或者是绑核不合理,绑了反而还不如系统自己来调度性能好

发表回复