最近負責的svr壓力比較大,業務邏輯有點複雜,能優化的地方已經全部優化了,
目前每秒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的時間
找了個例子:
現在多cpu的趨勢越來越大了. 有時候為了更好地操作機器, 需要將某個程序繫結到具體的cpu上去. 下面給出了乙個程序繫結到具體的cpu上去的乙個例子.
cpu.c
#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 0 ./cpu 2 後得到的結果. 效果比較明顯.
quote:
cpu0 : 5.3%us, 5.3%sy, 0.0%ni, 87.4%id, 0.0%wa, 0.0%hi, 2.0%si, 0.0%st
cpu1 : 0.0%us, 0.0%sy, 0.0%ni,100.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
cpu2 : 5.0%us, 12.2%sy, 0.0%ni, 82.8%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
cpu3 : 0.0%us, 0.0%sy, 0.0%ni,100.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
cpu4 : 0.0%us, 0.0%sy, 0.0%ni, 99.7%id, 0.3%wa, 0.0%hi, 0.0%si, 0.0%st
cpu5 : 0.0%us, 0.0%sy, 0.0%ni,100.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
cpu6 : 0.0%us, 0.0%sy, 0.0%ni,100.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
cpu7 : 0.0%us, 0.0%sy, 0.0%ni,100.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
///cpu affinity (cpu親合力)
cpu親合力就是指在linux系統中能夠將乙個或多個程序繫結到乙個或多個處理器上執行.
乙個程序的cpu親合力掩碼決定了該程序將在哪個或哪幾個cpu上執行.在乙個多處理器系統中,設定cpu親合力的掩碼可能會獲得更好的效能.
乙個cpu的親合力掩碼用乙個cpu_set_t結構體來表示乙個cpu集合,下面的幾個巨集分別對這個掩碼集進行操作:
cpu_zero() 清空乙個集合
cpu_set()與cpu_clr()分別對將乙個給定的cpu號加到乙個集合或者從乙個集合中去掉.
cpu_isset()檢查乙個cpu號是否在這個集合中.
其實這幾個的用法與select()函式那幾個呼叫差不多.
下面兩個函式就是最主要的了:
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.也表示的是當前程序.
這幾個巨集與函式的具體用法前面已經有講解.
關於cpu_set_t的定義
# define __cpu_setsize 1024
# define __ncpubits (8 * sizeof (__cpu_mask))
typedef unsigned long int __cpu_mask;
# define __cpuelt(cpu) ((cpu) / __ncpubits)
# define __cpumask(cpu) ((__cpu_mask) 1 << ((cpu) % __ncpubits))
typedef struct
cpu_set_t;
# define __cpu_zero(cpusetp) /
do while (0)
# define __cpu_set(cpu, cpusetp) /
((cpusetp)->__bits[__cpuelt (cpu)] |= __cpumask (cpu))
# define __cpu_clr(cpu, cpusetp) /
((cpusetp)->__bits[__cpuelt (cpu)] &= ~__cpumask (cpu))
# define __cpu_isset(cpu, cpusetp) /
(((cpusetp)->__bits[__cpuelt (cpu)] & __cpumask (cpu)) != 0)
在我的機器上sizeof(cpu_set_t)的大小為128,即一共有1024位.第一位代表乙個cpu號.某一位為1則表示某程序可以執行在該位所代表的cpu上.例如
cpu_set(1, &mask);
則mask所對應的第2位被設定為1.
此時如果printf("%d/n", mask.__bits[0]);就列印出2.表示第2位被置為1了.
具體我是參考man sched_setaffinity文件中的函式的.
然後再參考了一下ibm的 developerworks上的乙個講解.
linux下讓程序執行在指定的cpu上
最近負責的svr壓力比較大,業務邏輯有點複雜,能優化的地方已經全部優化了,目前每秒3k次,cpu負載還是比較高 top看一下,4核的cpu負載不是太均衡,打算考慮一下將業務程序指定到3個cpu上執行,另外乙個cpu專門負責處理網路收發包 打算嘗試一下,如果還是不行,再過段時間,訪問量再增加的話,就要...
linux下讓程序執行在指定的cpu上
收藏 最近負責的svr壓力比較大,業務邏輯有點複雜,能優化的地方已經全部優化了,目前每秒3k次,cpu負載還是比較高 top看一下,4核的cpu負載不是太均衡,打算考慮一下將業務程序指定到3個cpu上執行,另外乙個cpu專門負責處理網路收發包 打算嘗試一下,如果還是不行,再過段時間,訪問量再增加的話...
讓程序執行在指定的CPU
我的linode十分繁忙,在跑一些密集運算元據庫的rake任務時尤其如此。但我觀察發現,linode伺服器的4核cpu,只有第1個核心 cpu 0 非常忙,其他都處於idle狀態。不了解linux是如何排程的,但在linode的這種狀態下,顯然有優化的餘地。除了處理正常任務,cpu 0還需要處理各種...