什麼是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...