schedule 流程
可排程實體的vruntime、load計算
為什麼要先看fork的源**呢?
因為在schedule函式裡面一開始我就有點看不懂:
cpu = smp_processor_id();
按理來說很好理解呀,不就是獲取當前的cpu的id嗎?但是什麼叫做當前?在多處理器的機器上面,當前的定義是什麼?是在哪一塊cpu上面?我有點搞不懂,所以開始先看看fork都做了些什麼。
具體的流程可以看上面的圖,fork系統呼叫走到最後呼叫的是kernel/fork.c裡面的do_fork函式。
上圖中,我只是把我認為關鍵的函式提了出來。
從上面的圖可以看到do_fork有兩個主要的函式:
copy_process 和 wake_up_new_taskcopy_process 主要是對父程序task struct 的複製,做一些新程序的初始化,然後呼叫sched_fork函式。
sched_fork
主要就是這兩個函式,先獲取當前的cpu的id,好了,又是當前cpu,但是現在這個當前比較好理解:因為肯定是有乙個執行緒來呼叫fork這個函式的,不管是直接還是間接。這個執行緒能執行那肯定是在某一塊cpu上面,那麼get_cpu()函式就是獲取當前執行這個執行緒的cpu。然後暫時把新的執行緒的可執行cpu設定跟呼叫fork的執行緒一樣。
注意這裡只是暫時地設定,而且新的執行緒並沒有真正地執行在任何一塊cpu上面。
wake_up_new_task
主要的函式就是上面的這些,還是先獲取當前的cpu id,然後到了最重要的函式:select_task_rq,這個函式會根據新建立的這個執行緒所屬的排程類去執行不同的select_task_rq。
對於real time 任務
看當前在這個cpu上面執行的任務【當前任務】是不是realtime的,當前任務是否之能在這個cpu上面執行,新建的執行緒能否在其他的cpu上面執行。如果都滿足的話,就會呼叫find_lowest_rq來獲取可執行的cpu,否則直接返回當前的cpu。
對於normal任務(cfs)
先會根據cgroup,cpu_domain,task cpu親和性來選取適合的cpu,如果沒有這些要求的話,那麼會找到負載最低的cpu。
呼叫完這個函式之後,再呼叫set_task_cpu就設定相關的task struct 裡面的變數。最後再呼叫activate_task這個函式,activate_task又會呼叫enqueue_task這個函式,這個函式也是根據不同的排程類去呼叫不同的函式、
對於real time 任務
直接放入rt_rq對應優先順序的鍊錶尾。
對於normal任務(cfs)
放入cfs_rq的紅黑樹裡面。
好了,到這裡整個fork流程就結束了,只是粗略地走了一遍,很多細節等到需要閱讀相關模組的時候再深入。
看這個fork的流程的目的是知道smp_process_id()這個函式到底是獲得哪一塊cpu,現在已經清楚了,就是獲取當前程序執行的cpu,schedule函式也跟fork一樣,是被一些程序通過系統呼叫來呼叫的,所以能獲取當前程序的cpu。
schedule比較清晰,主要的函式只有三個
schedule
這個函式會根據不同的排程類來排程不同的函式,我暫時只看到了實時任務的排程類實現了這個函式。
會把其他cpu裡面的比當前cpu實時佇列的最高優先順序低的任務拉到當前的cpu實時佇列裡面。
這個就是主要的選取下乙個可以執行的任務的函式。
if (likely(rq->nr_running == rq->cfs.nr_running))
先是乙個小優化,然後再遍歷每個排程類來排程不同的函式
對於real time 任務
選取最高優先順序佇列鍊錶裡面的第乙個任務。
對於normal任務(cfs)
選取vrun_time最小的那個任務,紅黑樹最左邊的那個節點。
這個就是跟體系相關的上下文切換函式了,儲存暫存器裡面的值等等。
vruntime:
具體**在:kernel/sched_fair.c:__update_curr()
__update_curr()
update_delta_fair()
calc_delta_mine()
最主要的函式是最後乙個,裡面的計算邏輯除開對溢位的處理外,最後歸成下面的式子:
delta = delta * weight / lwload weight:對於cfs的計算,weight是nice值為0的程序weight:1024
lw是可排程實體的curr->load.weight
static const int prio_to_weight[40] = ;
max_rt_prio
set_load_weight()
通過上面可以看到,只有cfs的程序load weight有意義。同時這個load weight 在程序進入cpu的cfs rq的時候也會把這個值加到就緒佇列的load上面來反應這個cpu的負載程度。
《深入理解linux核心》《深入linux核心架構》
spark調優 shuffle調優
基於spark1.6 引數可以通過 new sparkcontext set 來設定,也可以通過命令的引數設定 conf spark.shuffle.file.buffer 預設值 32k 引數說明 該引數用於設定shuffle write task的bufferedoutputstream的buf...
Spark Spark調優 資源調優
spark在乙個executor的記憶體分為三塊,1.一塊是execution記憶體 2.一塊是storge 記憶體 3.一塊是其他記憶體 執行記憶體是執行記憶體,加入,聚合都是在這部分記憶體中執行.shuffle的資料也會先快取在這個記憶體中,滿了再寫入磁碟,能減少io,其實地圖過程也是在這個記憶...
尾調遞迴 ,尾調優化
尾調優化 title head body p pre 尾調優化,值得是函式最後一步呼叫了另乙個函式,函式呼叫會在內部形成乙個 呼叫記錄 儲存呼叫位置,內部變數等,a函式呼叫b函式,形成乙個 a到b的呼叫幀,直到結果返回,幀消失,b呼叫c函式,這樣,就形成了 呼叫棧,pre p h4 pre 尾調,不...