CPU affinity 进程和线程的亲缘性

设置Processor Affinity 作用:

  • 1.进程和线程的亲缘性(affinity),使进程或线程在指定的CPU(核)上运行.(比如程序A,在第4个核心上运行)
  • 2.设置进程 或者 线程, 使用CPU的数量(比如程序A,在第1,2,3个(共3个核心)核心上运行)
  • 3.CPU负载均衡

Processor_affinity @wiki

Specific operating systems

On Linux, the CPU affinity of a process can be altered with the taskset(1) program[2] and the sched_setaffinity(2) system call. The affinity of a thread can be altered with one of the library functions: pthread_setaffinity_np(3) or pthread_attr_setaffinity_np(3).

On Windows NT and its successors, thread and process CPU affinities can be set separately by using SetThreadAffinityMask[7] and SetProcessAffinityMask[8] API calls or via the Task Manager interface (for process affinity only).

"White Paper - Processor Affinity" - From tmurgent.com. Accessed 2007-07-06.

详细看wiki


一些帖子

管理处理器的亲和性 affinity

CPU Affinity (CPU亲合力)

Linux 线程绑核

假设业务模型中耗费cpu的分四种类型,(1)网卡中断(2)1个处理网络收发包进程(3)耗费cpu的n个worker进程(4)其他不太耗费cpu的进程

基于1中的 负载均衡是针对进程数,那么(1)(2)大部分时间会出现在cpu0上,(3)的n个进程会随着调度,平均到其他多个cpu上,(4)里的进程也是随着调度分配到各个cpu上;

当发生网卡中断的时候,cpu被打断了,处理网卡中断,那么分配到cpu0上的worker进程肯定是运行不了的

其他cpu上不是太耗费cpu的进程获得cpu时,就算它的时间片很短,它也是要执行的,那么这个时候,你的worker进程还是被影响到了;按照调度逻辑,一种非常恶劣的情况是:(1)(2)(3)的进程全部分配到cpu0上,其他不太耗费cpu的进程数很多,全部分配到cpu1,cpu2,cpu3上。。那么网卡中断发生的时候,你的业务进程就得不到cpu了

如果从业务的角度来说,worker进程运行越多,肯定业务处理越快,人为的将它捆绑到其他负载低的cpu上,肯定能提高worker进程使用cpu的时间


每个cpu都利用起来了,负载会比不绑定的情况下好很多

有效果的原因:

依据《linux内核设计与实现》的42节,人为控制一下cpu的绑定还是有用处地
    linux的SMP负载均衡是基于进程数的,每个cpu都有一个可执行进程队列(为什么不是线程队列呢??),只有当其中一个cpu的可执行队列里进程数比其他cpu队列进程数多25%时,才会将进程移动到另外空闲cpu上,也就是说cpu0上的进程数应该是比其他cpu上多,但是会在25%以内。

windows

SetProcessAffinityMask
GetProcessAffinityMask
SetThreadAffinityMask
SetThreadIdealProcessor

.....
SetThreadAffinityMask - MSDN Library
SetProcessAffinityMask - MSDN Library

linux

"taskset" at LinuxCommand.org. Accessed 2007-07-06.

中文 sched_setaffinity

pthread_getaffinity_np(3)
pthread_setaffinity_np(3)

pthread_attr_getaffinity_np(3)
pthread_attr_setaffinity_np(3)

BSD

cpuset(1) - FreeBSD manpage

"RN affinity API". Developer.apple.com


golang多平台

让Golang利用多核CPU能力来计算π的值

使用go的routines和channel,可以充分利用多核处理器,提高高CPU资源占用计算的速度。如下列计算π的值

package main

import (
    "fmt"
    "runtime"
    "time"
)

var n int64 = 10000000000
var h float64 = 1.0 / float64(n)

func f(a float64) float64 {
    return 4.0 / (1.0 + a*a)
}

func chunk(start, end int64, c chan float64) {
    var sum float64 = 0.0
    for i := start; i < end; i++ {
        x := h * (float64(i) + 0.5)
        sum += f(x)
    }
    c <- sum * h
}

func main() {

    //记录开始时间
    start := time.Now()

    var pi float64
    np := runtime.NumCPU()
    runtime.GOMAXPROCS(np)
    c := make(chan float64, np)

    for i := 0; i < np; i++ {
        go chunk(int64(i)*n/int64(np), (int64(i)+1)*n/int64(np), c)
    }

    for i := 0; i < np; i++ {
        pi += <-c
    }

    fmt.Println("Pi: ", pi)

    //记录结束时间
    end := time.Now()

    //输出执行时间,单位为毫秒。
    fmt.Printf("spend time: %vs\n", end.Sub(start).Seconds())
}

posted @ 2015-11-09 14:27  scott_h  阅读(1545)  评论(0编辑  收藏  举报