java 线程亲缘性_CPU affinity 进程和线程的亲缘性

设置Processor Affinity 作用:

1.进程和线程的亲缘性(affinity),使进程或线程在指定的CPU(核)上运行.(比如程序A,在第4个核心上运行)

2.设置进程 或者 线程, 使用CPU的数量(比如程序A,在第1,2,3个(共3个核心)核心上运行)

3.CPU负载均衡

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

一些帖子

假设业务模型中耗费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

linux

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

BSD

cpuset(1) - FreeBSD manpage

"RN affinity API". Developer.apple.com

golang多平台

使用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

}

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 +=

}

fmt.Println("Pi: ", pi)

//记录结束时间

end := time.Now()

//输出执行时间,单位为毫秒。

fmt.Printf("spend time: %vs\n", end.Sub(start).Seconds())

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值