如何將程序 執行緒繫結到固定的CPU核

2021-06-08 20:21:32 字數 4507 閱讀 8901

什麼是cpu affinity

?affinity

是程序的乙個屬性,這個屬性指明了程序排程器能夠把這個程序排程到哪些

cpu上。

在linux

中,我們可以利用

cpu affinity 

把乙個或多個程序繫結到乙個或多個

cpu上。

cpu affinity分為2

種,soft affinity

和hard affinity

。soft affinity

僅是乙個建議,如果不可避免,排程器還是會把程序排程到其它的

cpu上。

hard affinity

是排程器必須遵守的規則。

為什麼需要

cpu繫結?●增加

cpu快取的命中率

cpu之間是不共享快取的,如果程序頻繁的在各個

cpu間進行切換,需要不斷的使舊

cpu的

cache

失效。如果程序只在某個

cpu上執行,則不會出現失效的情況。●增加

cpu快取的命中率

在多個執行緒操作的是相同的資料的情況下,如果把這些執行緒排程到乙個處理器上,大大的增加了

cpu快取的命中率。但是可能會導致併發效能的降低。如果這些執行緒是序列的,則沒有這個影響。●適合

time-sensitive應用在

real-time

或time-sensitive

應用中,我們可以把系統程序繫結到某些

cpu上,把應用程序繫結到剩餘的

cpu上。典型的設定是,把應用繫結到某個

cpu上,把其它所有的程序繫結到其它的

cpu上。

#define _gnu_source

#include long sched_setaffinity(pid_t pid, unsigned int len,

unsigned long *user_mask_ptr);

long sched_getaffinity(pid_t pid, unsigned int len,

unsigned long *user_mask_ptr);

從函式名以及引數名都很明了,唯一需要解釋的是第三個引數,

這個引數

select

中的fd_set

比較類似,每個

bit代表乙個

cpu。

//設定

affinity

的例子

unsigned long mask = 7; /* processors 0, 1, and 2 */

unsigned int len = sizeof(mask);

sched_setaffinity(0, len, &mask);

//

設定獲取

affinity

的例子

unsigned long mask;

unsigned int len = sizeof(mask);

sched_getaffinity(0, len, &mask);

printf("my affinity mask is: %08lx\n", mask);

我們也可以不修改源**來繫結

cpu,前提是你必須是

root

使用者或者是程序的

owner

。參見第

6.1節。

與程序的情況相似,執行緒親和性的設定和獲取主要通過下面兩個函式來實現:

int pthread_setaffinity_np(pthread_t thread, size_t cpusetsize,const cpu_set_t *cpuset);

int pthread_getaffinity_np(pthread_t thread, size_t cpusetsize, cpu_set_t *cpuset);

從函式名以及引數名都很明了,唯一需要點解釋下的可能就是

cpu_set_t

這個結構體了。這個結構體的理解類似於

select

中的fd_set

,可以理解為

cpu集,也是通過約定好的巨集來進行清除、設定以及判斷:

//初始化,設為空

void cpu_zero (cpu_set_t *set);

//將某個cpu加入cpu集中

void cpu_set (int cpu, cpu_set_t *set);

//將某個cpu從cpu集中移出

void cpu_clr (int cpu, cpu_set_t *set);

//判斷某個cpu是否已在cpu集中設定了

int cpu_isset (int cpu, const cpu_set_t *set);

cpu

集可以認為是乙個掩碼,每個設定的位都對應乙個可以合法排程的

cpu,而未設定的位則對應乙個不可排程的

cpu。換而言之,執行緒都被繫結了,只能在那些對應位被設定了的處理器上執行。通常,掩碼中的所有位都被置位了,也就是可以在所有的

cpu中排程。

6.2小節是執行緒繫結

cpu的例子。

如何實現乙個或多個程序獨佔乙個或多個

cpu?

即排程器只能把指定的程序排程至指定的

cpu。最簡單的方法是利用

fork()

的繼承特性,子程序繼承父程序的

affinity

。這種方法無需修改和編譯核心**。

init

程序是所有程序的祖先,我們可以設定

init

程序的affinity

來達到設定所有程序的

affinity

的目地,然後把我們自己的程序繫結到目地

cpu上。這樣就到達了在指定

cpu上只執行指定的的程序的目地。

那麼,如何修改

init

程序的affinity

?我們只需在

/etc/rc.d/rc.sysinit

或/etc/rc.sysinit

中,起始處增加如下兩行,其中

bind

是6.1

小節編譯生成的可執行檔案,

rc.sysinit

檔案是init

程序執行的第乙個指令碼。

/bin/bind 1 1#

繫結init

程序至處理器

0

/bin/bind $$ 1#

繫結當前程序至處理器

0

通過核心引數

isolcpus

來指示系統保留

cpu。然後把目標執行緒繫結至保留的

cpu。

/* bind - ****** command-line tool to set cpu

* affinity of a given task

*/#define _gnu_source

#include #include #include int main(int argc, char *argv)

pid = atol(argv[1]);

sscanf(argv[2], "%08lx", &new_mask);

if (sched_getaffinity(pid, len,

&cur_mask) < 0)

printf("pid %d's old affinity: %08lx\n",

pid, cur_mask);

if (sched_setaffinity(pid, len, &new_mask))

if (sched_getaffinity(pid, len,

&cur_mask) < 0)

printf(" pid %d's new affinity: %08lx\n",

pid, cur_mask);

return 0;

}

#define _gnu_source

#include #include #include #include #include #include void *myfun(void *arg)

cpu_zero(&get);

if (pthread_getaffinity_np(pthread_self(), sizeof(get), &get) < 0)

for (j = 0; j < num; j++)

}j = 0;

while (j++ < 100000000)

}pthread_exit(null);}

int main(int argc, char *argv)

pthread_join(tid, null);

return 0;

}

[1] 

[2] 

如何將網域名稱繫結到hexo

1.擁有乙個githubname.github.io可以正常訪問的網域名稱,如我的github部落格 2.購買網域名稱,個人推薦阿里雲,首年年費比較便宜,適合個人折騰,部落格建議com,me,info,pro 專家 mobi kindle電子書的格式 再不濟可以選擇tech,cc之類的,國外可以參考...

windows下繫結執行緒(程序)到指定的CPU核心

乙個程式指定到單獨乙個cpu上執行會比不指定cpu執行時快。這中間主要有兩個原因 1 cpu切換時損耗的效能。2 intel的自動降頻技術和windows的機制衝突 windows有乙個功能是平衡負載,可以將乙個執行緒在不同時間分配到不同cpu,從而使得每乙個cpu不 過累 然而,inter又有乙個...

如何將陣列型別繫結到DataGridView控制項

datagridview控制項的datasource有以下幾個型別 datagridview 類支援標準的 windows 窗體資料繫結模型。這意味著資料來源可以是實現下列介面之一的任何型別 陣列如果直接繫結到datagridview控制項,會並不見得得到你想要的結果。下面是乙個示例 private...