在每個cpu上乙個乙個的執行:
for_each_online_cpu(cpu)
在每個cpu上執行:
on_each_cpu(hardware_enable, null, 0, 1);
r = register_cpu_notifier(&kvm_cpu_notifier);
if (r)
goto out_free_2;
register_reboot_notifier(&kvm_reboot_notifier);
cpumask_t cpus_hardware_enabled;
int cpu = raw_smp_processor_id();
if (cpu_isset(cpu, cpus_hardware_enabled))
return;
cpu_set(cpu, cpus_hardware_enabled);
在userspac中的使用:
在伺服器上,我們經常會有多個cpu的情況,而此時如果把程序都繫結在乙個cpu上,那麼對資源太多浪費了,下面的**就實現了如何將程式繫結在不同的cpu上。傳入引數代表繫結第幾個cpu(從0開始計算)
//cpu_test.cpp
#include
#include
#include
#include
#include
//#define __use_gnu
#include
#include
#include
int main(int argc, char* argv)
myid = atoi(argv[1]);
printf("system has %i processor(s). \n", num);
cpu_zero(&mask);
cpu_set(myid, &mask);
if (sched_setaffinity(0, sizeof(mask), &mask) == -1)
while (1)
for (i = 0; i < num; i++) }
} return 0;
} 下面解釋一下,裡面用到的函式:
首先解釋一下乙個叫cpu親和力(cpu affinity)的概念
cpu親合力就是指在linux系統中能夠將乙個或多個程序繫結到乙個或多個處理器上執行.
乙個程序的cpu親合力掩碼決定了該程序將在哪個或哪幾個cpu上執行.在乙個多處理器系統中,設定cpu親合力的掩碼可能會獲得更好的效能.
乙個cpu的親合力掩碼用乙個cpu_set_t結構體來表示乙個cpu集合,下面的幾個巨集分別對這個掩碼集進行操作:
cpu_zero() 清空乙個集合
cpu_set()與cpu_clr()分別對將乙個給定的cpu號加到乙個集合或者從乙個集合中去掉.
cpu_isset()檢查乙個cpu號是否在這個集合中.
而下面的函式實現了pid繫結對應cpu的過程:
sched_setaffinity(pid_t pid, unsigned int cpusetsize, cpu_set_t *mask)
該函式設定程序為pid的這個程序,讓它執行在mask所設定的cpu上.如果pid的值為0,則表示指定的是當前程序,使當前程序執行在mask所設定的那些cpu上.第二個引數cpusetsize是 mask所指定的數的長度.通常設定為sizeof(cpu_set_t).如果當前pid所指定的cpu此時沒有執行在mask所指定的任意乙個cpu上,則該指定的程序會從其它cpu上遷移到mask的指定的 乙個cpu上執行.
sched_getaffinity(pid_t pid, unsigned int cpusetsize, cpu_set_t *mask)
該函式獲得pid所指示的程序的cpu位掩碼,並將該掩碼返回到mask所指向的結構中.即獲得指定pid當前可以執行在哪些cpu上.同樣,如果pid的值為0.也表示的是當前程序.
目前每秒3k次,cpu負載還是比較高
top看一下,4核的cpu負載不是太均衡,打算考慮一下將業務程序指定到3個cpu上執行,另外乙個cpu專門負責處理網路收發包;打算嘗試一下,如果還是不行,再過段時間,訪問量再增加的話,就要加機器了
補充:今天測試了一下,效果挺好,同樣程序數的情況下,進行cpu繫結
每個cpu都利用起來了,負載也比不繫結的情況下好了很多
分析一下有效果的原因:
看了《linux核心設計與實現》的42節,覺得人為控制一下cpu的繫結還是有用處的
1、linux的smp負載均衡是基於程序數的,每個cpu都有乙個可執行程序佇列,只有當其中乙個cpu的可執行佇列裡程序數比其他cpu佇列程序數多25%時,才會將程序移動到另外空閒cpu上,也就是說cpu0上的程序數應該是比其他cpu上多,但是會在25%以內
2、我們的業務中耗費cpu的分四種型別,(1)網絡卡中斷(2)1個處理網路收發包程序(3)耗費cpu的n個worker程序(4)其他不太耗費cpu的程序
基於1中的 負載均衡是針對程序數,那麼(1)(2)大部分時間會出現在cpu0上,(3)的n個程序會隨著排程,平均到其他多個cpu上,(4)裡的程序也是隨著排程分配到各個cpu上;
當發生網絡卡中斷的時候,cpu被打斷了,處理網絡卡中斷,那麼分配到cpu0上的worker程序肯定是執行不了的
其他cpu上不是太耗費cpu的程序獲得cpu時,就算它的時間片很短,它也是要執行的,那麼這個時候,你的worker程序還是被影響到了;按照排程邏輯,一種非常惡劣的情況是:(1)(2)(3)的程序全部分配到cpu0上,其他不太耗費cpu的程序數很多,全部分配到cpu1,cpu2,cpu3上。。那麼網絡卡中斷發生的時候,你的業務程序就得不到cpu了
如果從業務的角度來說,worker程序執行越多,肯定業務處理越快,人為的將它**到其他負載低的cpu上,肯定能提高worker程序使用cpu的時間
關於linux的系統CPU和使用者CPU時間
轉過來學習用 所謂的時鐘時間又叫做牆上時鐘時間,它是程序執行的時鐘總量,其值與系統中同時執行的程序數有關,不過一般在討論時鐘時間的時候都是在系統中沒有其他活動進行時度量的。使用者cpu時間 就是執行使用者指令所用的時間。系統cpu時間 所謂的系統,我們知道就是在核心中執行的時間,沒錯滴,就是該程序執...
關於linux中的延時函式
應用程式 include usleep n n微秒 sleep n n毫秒 sleep n n秒 驅動程式 include mdelay n milliseconds 其實現 ifdef notdef define mdelay n else define mdelay n builtin cons...
關於linux中的延時函式
應用程式 include sleep n n秒 驅動程式 include mdelay n milliseconds 其實現 ifdef notdef define mdelay n else define mdelay n builtin constant p n n max udelay ms ...