成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Linux 進程管理之任務綁定

系統 Linux
將進程與 CPU 進行綁定可以提高 CPU 緩存的命中率,從而提高性能。這種綁定關系就叫做:進程的 CPU 親和性。

[[405508]]

本文轉載自微信公眾號「人人都是極客」,作者布道師Peter 。轉載本文請聯系人人都是極客公眾號。

什么是進程的 CPU 親和性?

在多核結構中,每個核有各自的L1緩存,相同類型的核被劃分在同一個cluster中,而不同cluster之間又有共用的L2緩存。講負載均衡的時候我們講過一個進程在核之間來回切換的時候,各個核之間的緩存命中率會降低,所以,將進程與 CPU 進行綁定可以提高 CPU 緩存的命中率,從而提高性能。這種綁定關系就叫做:進程的 CPU 親和性。

如何設置進程的 CPU 親和性?

Linux 系統提供了一個名為 sched_setaffinity 的系統調用,此系統調用可以設置進程的 CPU 親和性。

  1. sched_setaffinity(pid_t pid, size_t cpusetsize, const cpu_set_t *mask) 
  • pid:進行綁定 CPU 的進程ID號
  • cpusetsize:參數 mask 指向的 CPU 集合的大小
  • mask:與進程綁定的 CPU 集合

cpu_set_t 類型是個位圖,可以理解為 CPU 集,通過宏來進行清除、設置以及判斷:

  1. //初始化,設為空 
  2. void CPU_ZERO (cpu_set_t *set);  
  3. //將某個cpu加入cpu集中  
  4. void CPU_SET (int cpu, cpu_set_t *set);  
  5. //將某個cpu從cpu集中移出  
  6. void CPU_CLR (int cpu, cpu_set_t *set);  
  7. //判斷某個cpu是否已在cpu集中設置了  
  8. int CPU_ISSET (int cpu, const cpu_set_t *set); 

CPU 集可以認為是一個掩碼,每個設置的位都對應一個可以合法調度的 CPU,而未設置的位則對應一個不可調度的 CPU。換言之,線程都被綁定了,只能在那些對應位被設置了的處理器上運行。通常,掩碼中的所有位都被置位了,也就是可以在所有的 CPU 中調度。

我們來看看 sched_setaffinity 系統調用的例子,將進程綁定到 CPU2 上運行:

  1. #define _GNU_SOURCE 
  2. #include <sched.h> 
  3. #include <stdio.h> 
  4. #include <string.h> 
  5. #include <stdlib.h> 
  6. #include <unistd.h> 
  7. #include <errno.h> 
  8.  
  9. int main(int argc, char **argv) 
  10.     int cpus = 0; 
  11.     int  i = 0; 
  12.     cpu_set_t mask; 
  13.     cpu_set_t get; 
  14.  
  15.     cpus = sysconf(_SC_NPROCESSORS_ONLN); 
  16.     printf("cpus: %d\n", cpus); 
  17.  
  18.     CPU_ZERO(&mask);    /* 初始化set集,將set置為空*/ 
  19.     CPU_SET(2, &mask);  /*將本進程綁定到CPU2上*/ 
  20.     if (sched_setaffinity(0, sizeof(mask), &mask) == -1) { 
  21.         printf("Set CPU affinity failue, ERROR:%s\n", strerror(errno)); 
  22.         return -1;  
  23.     }    
  24.         
  25.     return 0; 

CPU 親和性的實現

我們知道每個 CPU 都擁有一個獨立的可運行進程隊列,系統運行的時候 CPU 只會從屬于自己的可運行進程隊列中按照 CFS 策略,選擇一個進程來運行。所以,把進程放置在 CPU 對應的可運行進程隊列上,也就可將進程綁定到指定的 CPU 上。

下面我們追蹤函數 sched_setaffinity 的調用順序,分析一下進程如何與 CPU 進行綁定的。

  1. SYSCALL_DEFINE3(sched_setaffinity, pid_t, pid, unsigned int, len, unsigned long __user *, user_mask_ptr) 
  2. -- sched_setaffinity(pid_t pid, const struct cpumask *in_mask) 
  3. --- __set_cpus_allowed_ptr(struct task_struct *p, const struct cpumask *new_mask, bool check) 
  4. ---- stop_one_cpu(unsigned int cpu, cpu_stop_fn_t fn, void *arg) 
  5. ----- migration_cpu_stop(void *data) 
  6. ------ __migrate_task(struct rq *rq, struct task_struct *p, int dest_cpu) 
  7. ------- move_queued_task(struct rq *rq, struct task_struct *p, int new_cpu) 
  8. -------- enqueue_task(struct rq *rq, struct task_struct *p, int flags) 
  9. --------- returns the new run queue of destination CPU 

__set_cpus_allowed_ptr 函數主要分兩種情況來將進程綁定到某個 CPU 上:

  1. stop_one_cpu(cpu_of(rq), migration_cpu_stop, &arg):把還沒運行且在源運行隊列中進程,放到指定的 CPU 可運行隊列中
  2. move_queued_task(rq, &rf, p, dest_cpu):把已經運行的進程遷移到指定的 CPU 可運行隊列中

這兩種情況最終都會調用 move_queued_task:

  1. static struct rq *move_queued_task(struct rq *rq, struct rq_flags *rf, 
  2.        struct task_struct *p, int new_cpu) 
  3.  lockdep_assert_held(&rq->lock); 
  4.  
  5.  p->on_rq = TASK_ON_RQ_MIGRATING; 
  6.  dequeue_task(rq, p, DEQUEUE_NOCLOCK); 
  7.  set_task_cpu(p, new_cpu); 
  8.  rq_unlock(rq, rf); 
  9.  
  10.  rq = cpu_rq(new_cpu); 
  11.  
  12.  rq_lock(rq, rf); 
  13.  BUG_ON(task_cpu(p) != new_cpu); 
  14.  enqueue_task(rq, p, 0); 
  15.  p->on_rq = TASK_ON_RQ_QUEUED; 
  16.  check_preempt_curr(rq, p, 0); 
  17.  
  18.  return rq; 

這里首先根據目標 CPU 找到對應的工作隊列 rq,然后通過 enqueue_task 把任務遷移到目標 CPU 對應的工作隊列中,CFS 調度器的話會調用到函數 enqueue_task_fair。

enqueue_task_fair 的執行流程如下:

  1. 如果通過struct sched_entity 的 on_rq 成員判斷進程已經在就緒隊列上, 則無事可。

 

否則, 具體的工作委托給 enqueue_entity,將任務插入到 CFS 紅黑樹中合適的結點。

 

責任編輯:武曉燕 來源: 人人都是極客
相關推薦

2011-01-11 13:47:27

Linux管理進程

2023-03-05 16:12:41

Linux進程線程

2023-03-02 23:50:36

Linux進程管理

2023-03-03 00:03:07

Linux進程管理

2021-04-15 05:51:25

Linux

2021-04-22 07:47:46

Linux進程管理

2023-03-05 15:28:39

CFSLinux進程

2021-05-17 18:28:36

Linux CFS負載均衡

2021-05-12 07:50:02

CFS調度器Linux

2010-02-25 10:28:43

Linux進程管理

2011-01-14 14:49:05

2009-10-23 17:35:16

linux進程管理

2014-08-01 15:38:37

Linux進程管理

2017-03-03 10:10:44

Linux進程管理基礎知識

2011-01-11 13:53:33

Linux管理磁盤

2021-07-06 21:30:06

Linux進程通信

2009-10-27 16:34:02

linux top命令

2010-07-21 09:32:03

Linux多核

2013-10-11 14:51:16

Linux進程管理

2021-03-17 21:34:44

Linux內存管理
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日韩精品视频在线观看一区二区三区 | 亚洲精品国产成人 | 韩日一区二区 | 欧美精品1区2区3区 精品国产欧美一区二区 | 日韩精品一区二区三区视频播放 | 91社区在线观看高清 | 欧美激情久久久 | 一本在线| 精品国产精品国产偷麻豆 | 欧美日韩一区二区三区四区 | 国产精品一区一区三区 | 播放一级黄色片 | 福利视频二区 | 欧美日韩在线观看视频网站 | 亚洲精品18| 久久天堂网 | 精品免费国产视频 | 亚洲精品乱码久久久久久9色 | 无毛av| 九九热精品视频 | 亚洲一区二区视频 | 人人擦人人 | 欧美在线天堂 | 久久久久亚洲 | 亚洲精品国产成人 | 国产一区二区免费在线 | 黄色一级视频免费 | 欧美伊人久久久久久久久影院 | 国产亚洲精品综合一区 | 一区二区视频在线 | 精国产品一区二区三区 | 成人一区二 | 中文字幕在线观看视频网站 | 日本黄色的视频 | 日韩视频区 | av中文天堂 | 五月天国产视频 | 欧美综合一区二区 | www.久久.com| 欧洲一区二区三区 | 欧美日韩国产综合在线 |