动态修改CPU Affinity

多核并行程序如果设置不好cpu affinity,程序运行性能会有可能达到10倍的差距,我所见过的多线程程序每个thread都会在程序当中给绑定特定的core;但是假如是进程,也就是启动某一个程序,一般会人为地通过taskset来强制指定该程序运行在哪一个或者哪几个core上,让他们乖乖得呆着,避免冲突

假如程序已经运行,不希望停止该进程,动态修改它运行的core,让它运行在core_array这个包含core id的列表中,可做如下操作:

pid=`pgrep XXX`

taskset -cp core_array pid

如:将ssh运行的core id进行修改

[lihui@2014 ~]$ pgrep ssh
2276

[lihui@2014 ~]$ ps -eo pid,psr | grep 2276
2276    0

[lihui@2014 ~]$ sudo taskset -cp 1 2276

[lihui@2014 ~]$ ps -eo pid,psr | grep 2276
2276    1

ps -eo pid,psr | grep pid的意思就是查找该pid执行的core id编号,上面ssh运行的core id从0变成了1上

假如是fork出来的多进程程序,父进程可能是通过源代码里已经绑定好了核,但是子进程较多,而且处理量比较大,不希望继承父进程的cpu affinity(不做处理子进程是会继承父进程的亲和特性),因此也可以进行手动动态修改

首先你可以得到每一个子进程的进程名称,然后通过pgrep一个一个得到进程号,进而taskset -cp进行动态修改

假如子进程和父进程进程名一致,那么pgrep process_name会得到很多行进程号,但是第一行肯定是父进程的进程id,你也可以确认一下,进程号是否最小,最小的是父进程id,那么就仅仅需要动态修改除了第一行id外其它的cpu affinity,也可以通过以下脚本修改:

#!/usr/bin/perl -w

my $process_pid = `pgrep XXXX`;
my @process_array = split /\n/, $process_pid;

#main process
my $main_pid = $pid_array[0];
system “taskset -cp main_core_id $main_pid”;

#fork process
foreach my $id ( 1 … $#pid_array ){
system “taskset -cp child_core_id $pid_array[$id]“;
}

其中main_core_id是主进程需要动态修改的core id,如果不需要可注释掉那两行;child_core_id是子进程需要修改的core id

发表评论