多核编程与CPU亲和力

多核编程

多核编程和多线程编程还是有一些差异的,对于多线程编程,我们可以创建多个线程去处理业务,但是不会关心具体哪个进程运行在哪个CPU上,而多核的意思则是可以把特定任务绑定到特定的CPU上运行。这样的好处是什么?能够把重要的任务独立到一个CPU上运行,从而不受其他任务影响,提升该任务的响应速度。通过CPU绑定也能提升cache命中率,从而提高性能。具体到使用上,就是利用如下API绑定CPU:

int sched_setaffinity(pid_t pid, size_t cpusetsize,
 cpu_set_t *mask);

int sched_getaffinity(pid_t pid, size_t cpusetsize,
 cpu_set_t *mask);

内核实现

long sched_setaffinity(pid_t pid, const struct cpumask *in_mask)
{

......
	cpuset_cpus_allowed(p, cpus_allowed);
	cpumask_and(new_mask, in_mask, cpus_allowed);
	retval = set_cpus_allowed_ptr(p, new_mask);
......
}

这个函数中有关键的3个步骤,取出当前task进程中的cpus_allowed bitmap mask,然后通过cpumask_and与in_mask进行位与操作,最后把cpuset mask设置到对应的task进程结构体中set_cpus_allowed_ptr,这个函数的目的就是把pid对应进程绑定到in_mask中指定的cpu上运行。下面看一下cpus_allowed是在哪里生效的:

static inline
int select_task_rq(struct task_struct *p, int cpu, int sd_flags, int wake_flags)
{
    if (p->nr_cpus_allowed > 1)
        cpu = p->sched_class->select_task_rq(p, cpu, sd_flags, wake_flags);

    /*
     * In order not to call set_task_cpu() on a blocking task we need
     * to rely on ttwu() to place the task on a valid ->cpus_allowed
     * cpu.
     *
     * Since this is common to all placement strategies, this lives here.
     *
     * [ this allows ->select_task() to simply return task_cpu(p) and
     *   not worry about this generic constraint ]
     */
    if (unlikely(!cpumask_test_cpu(cpu, tsk_cpus_allowed(p)) ||
             !cpu_online(cpu)))
        cpu = select_fallback_rq(task_cpu(p), p);

    return cpu;
}

这里当进程wakeup或者fork时,内核会执行到select_task_rq函数,该函数中会对cpus_allowed进行检测,对于当前进程不允许的cpu,会对该进程重新选择runqueue,把当前进程放到允许运行的cpu runqueue上:

if (unlikely(!cpumask_test_cpu(cpu, tsk_cpus_allowed(p)) ||
             !cpu_online(cpu)))
        cpu = select_fallback_rq(task_cpu(p), p);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值