一区二区三区三上|欧美在线视频五区|国产午夜无码在线观看视频|亚洲国产裸体网站|无码成年人影视|亚洲AV亚洲AV|成人开心激情五月|欧美性爱内射视频|超碰人人干人人上|一区二区无码三区亚洲人区久久精品

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

把進程綁定到某個 CPU 上運行是怎么實現(xiàn)?

Linux愛好者 ? 來源:Linux內(nèi)核那些事 ? 作者:songsong001 ? 2021-07-02 09:55 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

昨天在群里有朋友問:把進程綁定到某個 CPU 上運行是怎么實現(xiàn)的。

首先,我們先來了解下將進程與 CPU 進行綁定的好處。

進程綁定 CPU 的好處:在多核 CPU 結(jié)構(gòu)中,每個核心有各自的L1、L2緩存,而L3緩存是共用的。如果一個進程在核心間來回切換,各個核心的緩存命中率就會受到影響。相反如果進程不管如何調(diào)度,都始終可以在一個核心上執(zhí)行,那么其數(shù)據(jù)的L1、L2 緩存的命中率可以顯著提高。

所以,將進程與 CPU 進行綁定可以提高 CPU 緩存的命中率,從而提高性能。而進程與 CPU 綁定被稱為:CPU 親和性。

設(shè)置進程的 CPU 親和性前面介紹了進程與 CPU 綁定的好處后,現(xiàn)在來介紹一下在 Linux 系統(tǒng)下怎么將進程與 CPU 進行綁定的(也就是設(shè)置進程的 CPU 親和性)。

Linux 系統(tǒng)提供了一個名為 sched_setaffinity 的系統(tǒng)調(diào)用,此系統(tǒng)調(diào)用可以設(shè)置進程的 CPU 親和性。我們來看看 sched_setaffinity 系統(tǒng)調(diào)用的原型:

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

下面介紹一下 sched_setaffinity 系統(tǒng)調(diào)用各個參數(shù)的作用:

pid:進程ID,也就是要進行綁定 CPU 的進程ID。

cpusetsize:mask 參數(shù)所指向的 CPU 集合的大小。

mask:與進程進行綁定的 CPU 集合(由于一個進程可以綁定到多個 CPU 上運行)。

參數(shù) mask 的類型為 cpu_set_t,而 cpu_set_t 是一個位圖,位圖的每個位表示一個 CPU。:

例如,將 cpu_set_t 的第0位設(shè)置為1,表示將進程綁定到 CPU0 上運行,當(dāng)然我們可以將進程綁定到多個 CPU 上運行。

我們通過一個例子來介紹怎么通過 sched_setaffinity 系統(tǒng)調(diào)用來設(shè)置進程的 CPU 親和性:

#define _GNU_SOURCE#include 《sched.h》#include 《stdio.h》#include 《string.h》#include 《stdlib.h》#include 《unistd.h》#include 《errno.h》int main(int argc, char **argv)

{

cpu_set_t cpuset;

CPU_ZERO(&cpuset); // 初始化CPU集合,將 cpuset 置為空

CPU_SET(2, &cpuset); // 將本進程綁定到 CPU2 上

// 設(shè)置進程的 CPU 親和性

if (sched_setaffinity(0, sizeof(cpuset), &cpuset) == -1) {

printf(“Set CPU affinity failed, error: %s

”, strerror(errno));

return -1;

}

return 0;

}

CPU 親和性實現(xiàn)知道怎么設(shè)置進程的 CPU 親和性后,現(xiàn)在我們來分析一下 Linux 內(nèi)核是怎樣實現(xiàn) CPU 親和性功能的。

本文使用的 Linux 內(nèi)核版本為 2.6.23

Linux 內(nèi)核為每個 CPU 定義了一個類型為 struct rq 的 可運行的進程隊列,也就是說,每個 CPU 都擁有一個獨立的可運行進程隊列。

一般來說,CPU 只會從屬于自己的可運行進程隊列中選擇一個進程來運行。也就是說,CPU0 只會從屬于 CPU0 的可運行隊列中選擇一個進程來運行,而絕不會從 CPU1 的可運行隊列中獲取。

所以,從上面的信息中可以分析出,要將進程綁定到某個 CPU 上運行,只需要將進程放置到其所屬的 可運行進程隊列 中即可。

下面我們來分析一下 sched_setaffinity 系統(tǒng)調(diào)用的實現(xiàn),sched_setaffinity 系統(tǒng)調(diào)用的調(diào)用鏈如下:

sys_sched_setaffinity()

└→ sched_setaffinity()

└→ set_cpus_allowed()

└→ migrate_task()

從上面的調(diào)用鏈可以看出,sched_setaffinity 系統(tǒng)調(diào)用最終會調(diào)用 migrate_task 函數(shù)來完成進程與 CPU 進行綁定的工作,我們來分析一下 migrate_task 函數(shù)的實現(xiàn):

static int

migrate_task(struct task_struct *p, int dest_cpu, struct migration_req *req)

{

struct rq *rq = task_rq(p);

// 情況1:

// 如果進程還沒有在任何運行隊列中

// 那么只需要將進程的 cpu 字段設(shè)置為 dest_cpu 即可

if (!p-》se.on_rq && !task_running(rq, p)) {

set_task_cpu(p, dest_cpu);

return 0;

}

// 情況2:

// 如果進程已經(jīng)在某一個 CPU 的可運行隊列中

// 那么需要將進程從之前的 CPU 可運行隊列中遷移到新的 CPU 可運行隊列中

// 這個遷移過程由 migration_thread 內(nèi)核線程完成

// 構(gòu)建進程遷移請求

init_completion(&req-》done);

req-》task = p;

req-》dest_cpu = dest_cpu;

list_add(&req-》list, &rq-》migration_queue);

return 1;

}

我們先來介紹一下 migrate_task 函數(shù)各個參數(shù)的意義:

p:要設(shè)置 CPU 親和性的進程描述符。

dest_cpu:綁定的 CPU 編號。

req:進程遷移請求對象(下面會介紹)。

所以,migrate_task 函數(shù)的作用就是將進程描述符為 p 的進程綁定到編號為 dest_cpu 的目標(biāo) CPU 上。

migrate_task 函數(shù)主要分兩種情況來將進程綁定到某個 CPU 上:

情況1:如果進程還沒有在任何 CPU 的可運行隊列中(不可運行狀態(tài)),那么只需要將進程描述符的 cpu 字段設(shè)置為 dest_cpu 即可。當(dāng)進程變?yōu)榭蛇\行時,會根據(jù)進程描述符的 cpu 字段來自動放置到對應(yīng)的 CPU 可運行隊列中。

情況2:如果進程已經(jīng)在某個 CPU 的可運行隊列中,那么需要將進程從之前的 CPU 可運行隊列中遷移到新的 CPU 可運行隊列中。遷移過程由 migration_thread 內(nèi)核線程完成,migrate_task 函數(shù)只是構(gòu)建一個進程遷移請求,并通知 migration_thread 內(nèi)核線程有新的遷移請求需要處理。

而進程遷移過程由 __migrate_task 函數(shù)完成,我們來看看 __migrate_task 函數(shù)的實現(xiàn):

static int

__migrate_task(struct task_struct *p, int src_cpu, int dest_cpu)

{

struct rq *rq_dest, *rq_src;

int ret = 0, on_rq;

。。。

rq_src = cpu_rq(src_cpu); // 進程所在的原可運行隊列

rq_dest = cpu_rq(dest_cpu); // 進程希望放置的目標(biāo)可運行隊列

。。。

on_rq = p-》se.on_rq; // 進程是否在可運行隊列中(可運行狀態(tài))

if (on_rq)

deactivate_task(rq_src, p, 0); // 把進程從原來的可運行隊列中刪除

set_task_cpu(p, dest_cpu);

if (on_rq) {

activate_task(rq_dest, p, 0); // 把進程放置到目標(biāo)可運行隊列中

。。。

}

。。。

return ret;

}

__migrate_task 函數(shù)主要完成以下兩個工作:

把進程從原來的可運行隊列中刪除。

把進程放置到目標(biāo)可運行隊列中。

其工作過程如下圖所示(將進程從 CPU0 的可運行隊列遷移到 CPU3 的可運行隊列中):

如上圖所示,進程原本在 CPU0 的可運行隊列中,但由于重新將進程綁定到 CPU3,所以需要將進程從 CPU0 的可運行隊列遷移到 CPU3 的可運行中。

遷移過程首先將進程從 CPU0 的可運行隊列中刪除,然后再將進程插入到 CPU3 的可運行隊列中。

當(dāng) CPU 要運行進程時,首先從它所屬的可運行隊列中挑選一個進程,并將此進程調(diào)度到 CPU 中運行。

總結(jié)從上面的分析可知,其實將進程綁定到某個 CPU 只是將進程放置到 CPU 的可運行隊列中。

由于每個 CPU 都有一個可運行隊列,所以就有可能會出現(xiàn) CPU 間可運行隊列負(fù)載不均衡問題。如 CPU0 可運行隊列中的進程比 CPU1 可運行隊列多非常多,從而導(dǎo)致 CPU0 的負(fù)載非常高,而 CPU1 負(fù)載非常低的情況。

當(dāng)出現(xiàn)上述情況時,就需要對 CPU 間的可運行隊列進行重平衡操作,有興趣的可以自行閱讀源碼或參考相關(guān)資料。

編輯:jq

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 內(nèi)核
    +關(guān)注

    關(guān)注

    3

    文章

    1416

    瀏覽量

    41418
  • cpu
    cpu
    +關(guān)注

    關(guān)注

    68

    文章

    11077

    瀏覽量

    217022
  • Linux
    +關(guān)注

    關(guān)注

    87

    文章

    11509

    瀏覽量

    213741

原文標(biāo)題:圖解:進程怎么綁定 CPU

文章出處:【微信號:LinuxHub,微信公眾號:Linux愛好者】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點推薦

    STM32IDE如何設(shè)定代碼ITCM中運行?

    摸索到了如何將變量定義某個地址,但是不清楚如何讓代碼在指定RAM中運行。按照設(shè)定變量的方式設(shè)定代碼,程序直接進入了異常中斷{:16:}。
    發(fā)表于 06-24 06:45

    Linux后臺進程管理詳解

    當(dāng)我們在終端或控制臺工作時,可能不希望由于運行一個作業(yè)而占住了屏幕,因為可能還有更重要的事情要做,比如閱讀電子郵件。對于密集訪問磁盤的進程,我們更希望它能夠在每天的非負(fù)荷高峰時間段運行(例如凌晨)。為了使這些
    的頭像 發(fā)表于 04-25 11:04 ?410次閱讀
    Linux后臺<b class='flag-5'>進程</b>管理詳解

    無法在iMX8啟動gpsd:GPSD綁定怎么解決?

    3.19) gpsd:錯誤:無法綁定 IPv4 端口 gpsd,地址已在使用 gpsd:ERROR: 也許 gpsd 已經(jīng)在運行了! gpsd:錯誤:無法綁定
    發(fā)表于 04-04 07:58

    請問如何在Python中實現(xiàn)多線程與多進程的協(xié)作?

    () thread.join() process.join() 我的問題是:**如何合理地組合多線程和多進程以獲得更好的性能?**特別是在I/O密集型任務(wù)和CPU密集型任務(wù)混合的情況下,如何避免性能瓶頸,確保程序的高效運行? 希
    發(fā)表于 03-11 06:57

    CPU怎么降頻 bios中如何cpu調(diào)低頻率

    CPU降頻是一種有效的節(jié)能措施,同時也有助于降低設(shè)備的溫度和功耗,提高系統(tǒng)的穩(wěn)定性和使用壽命。以下將詳細(xì)介紹如何在操作系統(tǒng)中、BIOS設(shè)置里以及使用第三方軟件來實現(xiàn)CPU降頻。 一、在操作系統(tǒng)中降低
    的頭像 發(fā)表于 02-01 15:02 ?1.9w次閱讀

    深入解析Linux程序與進程

    關(guān)于某個數(shù)據(jù)集合的一次運行活動。作為系統(tǒng)進行資源分配和調(diào)度的基本單位,是操作系統(tǒng)結(jié)構(gòu)的基礎(chǔ)。 程序與進程的關(guān)系 進程的狀態(tài) 基礎(chǔ)進程狀態(tài) 創(chuàng)
    的頭像 發(fā)表于 12-18 11:01 ?477次閱讀
    深入解析Linux程序與<b class='flag-5'>進程</b>

    Linux之CPU調(diào)度策略和CPU親和性

    一、調(diào)度策略 調(diào)度進程 單個 CPU一次只能執(zhí)行一個進程,雖然 Linux 系統(tǒng)通過使用多任務(wù)同時處理多個進程,但當(dāng)多個進程同時
    的頭像 發(fā)表于 12-05 16:38 ?1097次閱讀
    Linux之<b class='flag-5'>CPU</b>調(diào)度策略和<b class='flag-5'>CPU</b>親和性

    fpga 管腳不讓綁定的問題,綁定時提示: Not assignable

    fpga 管腳不讓綁定的--提示 如下圖: 網(wǎng)上說將復(fù)用管腳設(shè)置成 普通I/O,我這也沒找到我要綁定的管腳,怎么設(shè)置。該管腳是和NOR_Flash相關(guān)的,無法綁定,我想實現(xiàn)掉電存儲一些
    發(fā)表于 12-05 15:30

    怎么綁定IP地址和MAC地址

    本篇文章主要說一說怎么在本地計算機上綁定IP和MAC地址以及通過路由器綁定IP和MAC地址,并且這兩者綁定可以解決什么問題。 ? 先來說說怎么去綁定 本地計算上
    的頭像 發(fā)表于 12-01 22:48 ?1365次閱讀

    程序和進程的區(qū)別

    比如: 開發(fā)寫的代碼我們稱為程序,那么將開發(fā)的代碼運行起來。我們稱為進程。
    的頭像 發(fā)表于 11-25 16:03 ?1232次閱讀
    程序和<b class='flag-5'>進程</b>的區(qū)別

    一文搞懂Linux進程的睡眠和喚醒

    的代碼和數(shù)據(jù),進而去執(zhí)行這個進程。下面列舉了一些進程狀態(tài): 注意:沒有+時,默認(rèn)是后臺進程 進程調(diào)度(進程狀態(tài)切換)
    發(fā)表于 11-04 15:15

    【軟件干貨】Android應(yīng)用進程如何?;??

    在Android應(yīng)用程序中,為了保證應(yīng)用的正常運行和穩(wěn)定性,有時需要對應(yīng)用進程進行?;?。以下是一些實現(xiàn)進程?;畹姆椒ǎ?/div>
    的頭像 發(fā)表于 10-15 17:05 ?1205次閱讀
    【軟件干貨】Android應(yīng)用<b class='flag-5'>進程</b>如何?;??

    TLV320AIC3104接在高通的CPU,采集的效果很差,為什么?

    我們TLV320AIC3104接在海思的CPU,在PCB設(shè)計的時候也沒有太注意,感覺效果還好,能接受,TLV320AIC3104接在高通的C
    發(fā)表于 10-15 07:49

    機智云智家APP的設(shè)備掃描與綁定限制

    版應(yīng)用,旨在實現(xiàn)對智能設(shè)備的管理和控制。通過智家APP,用戶可以方便地與支持的設(shè)備進行互動,享受智能家居帶來的便利。然而,綁定設(shè)備的能力并非對所有用戶開放。Q綁定設(shè)備的條件
    的頭像 發(fā)表于 09-22 08:02 ?588次閱讀
    機智云智家APP的設(shè)備掃描與<b class='flag-5'>綁定</b>限制

    rk3588s 怎么將gpio中斷綁定其它cpu

    目前了解只有GIC的中斷才能用這種:echo 2 > /proc/irq/102/smp_affinity, 方式綁定cpu,而GPIO這種是用不了這種方式綁定的。 想問下有其
    發(fā)表于 07-16 15:09