目錄
- 引言
- 何為cpu親緣性
- 使用親緣性的好處
- Linux CPU親緣性的使用
- 例子
- 參考-強推~
引言
關於cpu親緣性,文末參考連結講述的非常詳細,本文只記錄自己寫的一個小demo來了解cpu親緣性
何為cpu親緣性
所謂CPU親緣性可以分為兩大類:軟親緣性和硬親緣性。
- Linux 核心程序排程器天生就具有被稱為 CPU 軟親緣性(soft affinity) 的特性,這意味著程序通常不會在處理器之間頻繁遷移。這種狀態正是我們希望的,因為程序遷移的頻率小就意味著產生的負載小。但不代表不會進行小範圍的遷移。
- CPU 硬親緣性是指透過Linux提供的相關CPU親緣性設定介面,顯示的指定某個程序固定的某個處理器上執行。本文所提到的CPU親緣性主要是指硬親緣性
使用親緣性的好處
目前主流的伺服器配置都是SMP架構,在SMP的環境下,每個CPU本身自己會有快取,快取著程序使用的資訊,而程序可能會被kernel排程到其他CPU上(即所謂的core migration),如此,CPU cache命中率就低了。設定CPU親緣性,程式就會一直在指定的cpu執行,防止程序在多SMP的環境下的core migration,從而避免因切換帶來的CPU的L1/L2 cache失效。從而進一步提高應用程式的效能。
Linux CPU親緣性的使用
利用glibc庫中的sched_getaffinity介面,我們獲取應用程式當前的cpu親緣性,而透過sched_setaffinity介面則可以把應用程式繫結到固定的某個或某幾cpu上執行
#include <sched.h>
void CPU_ZERO(cpu_set_t *set);
void CPU_CLR(int cpu, cpu_set_t *set);
void CPU_SET(int cpu, cpu_set_t *set);
int CPU_ISSET(int cpu, cpu_set_t *set);
int sched_getaffinity(pid_t pid, unsigned int cpusetsize, cpu_set_t *mask);
int sched_setaffinity(pid_t pid, unsigned int cpusetsize, cpu_set_t *mask);
例子
- 使用
htop
命令檢視linux作業系統有4個cpu,每一個的負載都很低:
- 我們透過下面的程式碼,寫一個死迴圈並且親緣某個CPU來觀看是否能把CPU負載利用到100%
注意#define __USE_GNU
的位置,筆者也不知道為啥放在這裡可以編譯過,不放這裡會報undefine的錯誤
#include <stdio.h>
#define __USE_GNU
#include <pthread.h>
#include <unistd.h>
#include <sched.h>
#include <sys/types.h>
#include <sys/syscall.h>
void process_affinity(int num) {
// 作用同 : gettid();
pid_t selfpid = syscall(__NR_gettid);
cpu_set_t mask;
CPU_ZERO(&mask);
CPU_SET(selfpid % num, &mask);
// 設定cpu親緣性
sched_setaffinity(selfpid, sizeof(mask), &mask);
while(1) ; // 死迴圈
}
int main()
{
// 獲取CPU數
int num = sysconf(_SC_NPROCESSORS_CONF);
printf("cpu num = %d\n", num);
pid_t pid;
pid = fork();
if (pid < 0) {
printf("err\n");
return -1;
} else if (pid == 0) {
process_affinity(num); // 子程序,cpu親緣性
return 0;
}
// 父程序
printf("pid = %d\n", pid);
while (1) sleep(1);
return 0;
}
- 效果
果然,其中一個cpu被死迴圈的程序親緣而導致100%了,合理利用cpu親緣性,可以有效提高cpu負載利用率
參考-強推~
https://www.cnblogs.com/lojunren/p/3865232.html