我的任務是在用 C 或 C 撰寫的程式中測量 Linux 中執行緒的遷移時間。
我在空閑核心上運行單個執行緒(沒有親和性),然后為了強制調度程式進行負載平衡和遷移執行緒,我將第二個執行緒固定在同一個核心上。我們知道,一旦創建了新執行緒/行程,調度程式就會平衡執行緒,從而導致第一個執行緒從該核心遷移到最不忙的一個(因為第二個執行緒被固定到該核心)。
我想用高解析度計時器測量這個執行緒遷移時間。我試過perf sched了,但它只跟蹤遷移事件。澄清一下,延遲是指在核心上創建第二個執行緒的時間與第一個執行緒完全遷移到新核心的時間之間的差異。
我如何測量這種延遲?
uj5u.com熱心網友回復:
Kernelshark 是您完成這項任務的朋友。看看The Graph Window,尤其是 Task Plots (大約一半)。您必須將正確的選項編譯到您的內核中(首先是 FTRACE),并且需要一定的精細度來控制資料的捕獲,以便它包含您想要的事件,但是您可以獲得非常詳細的資訊在整機上進行。
基本上,你可以看到系統中每個執行緒的全部命運,它在哪個 CPU 上運行,何時,為什么等等。這里似乎有一個有用的教程
這種工具非常適合準確查看系統中發生的情況。其他東西也出現了,比如 CPU 時鐘速度電源模式切換(一切都可以無緣無故停止庫存)等。
uj5u.com熱心網友回復:
如果您使用的是現代 x86 CPU,則該rdtscp指令可能對于獲取納秒級精度的時間戳和內核 ID 作為單個 asm 指令很有用,因此兩者都來自同一個內核。Linux 將IA32_TSC_AUXMSR 設定為一個與它用于關聯的核心編號匹配的小整數,例如,在您從以下測驗程式中taskset -c 3 ./a.out獲得 a的情況下運行:ID = 3
#include <x86intrin.h>
#include <stdio.h>
int main(){
unsigned id;
unsigned long tsc = __rdtscp(&id);
printf("tsc = %ld ID = %d\n", tsc, id);
}
另請參閱如何從 C 獲取 x86_64 中的 CPU 周期計數?有關一般 TSC 的更多詳細資訊,以及大多數現代 x86 系統具有跨內核同步 TSC 的事實。(特別是在單插槽多核 CPU 中,但設計良好的多插槽主板也可以做到。)另外,TSC 以固定的參考頻率運行,而不是核心時鐘周期,因此它是掛鐘時間的代理.
因此,我們可以收集帶有時間戳的核心 ID 作為單個 asm 指令的一部分,這意味著兩者肯定來自同一個核心。(中斷不能出現在單條指令的中間。)這排除了某些問題。
您可以撰寫一個回圈,__rdtscp直到它看到核心 ID 更改,然后記錄或列印舊核心的最后一個 TSC 值和新核心的第一個 TSC 值。(還有增量,但您希望在啟動新執行緒或設定執行緒親和性之前將絕對 TSC 值與 TSC 進行比較。)
uint64_t spin_until_migration(some output args)
{
unsigned old_id, new_id;
uint64_t old_tsc;
uint64_t new_tsc = __rdtscp(&old_id);
do {
old_tsc = new_tsc;
new_tsc = __rdtscp(&new_id);
}while(old_id != new_id);
// *arg1 = old_tsc;
// ...
return new_tsc - old_tsc;
}
(在同一個內核上旋轉時,例如 Skylake 上的增量通常約為 32 個內核時鐘周期(https://uops.info/)。如果 CPU 的當前頻率接近其 TSC 參考頻率(通常接近其“額定“ 標定頻率,例如我的 i7-6700k 4.0GHz 和 4.2GHz turbo 上的 4008 MHz),這也是大約 32 個核心周期。更大的增量將發生在中斷處理程式或其他暫時停止用戶空間運行的事情上。)
請注意,此代碼僅測量此執行緒上次在舊核心上獲得時間片的時間。在固定執行緒已經在該內核上運行了一段時間之后,調度程式決定遷移執行緒可能會稍后做出。
您需要在競爭負載的各個步驟記錄 TSC 時間戳,例如在啟動新執行緒之前和之后。或者在進行遷移現有執行緒的 CPU 關聯系統呼叫之前/之后。我還沒有考慮完整的細節。
uj5u.com熱心網友回復:
您可以使用硬體性能計數器嗎?您沒有確切地說出您的 CPU 是什么,老實說,我無法為您提供很多有關細節的幫助,但是大多數 CPU 在某處都有一個回圈計數器。您可以將代碼寫入執行緒以快取計數器的值,然后您可以將其列印出來以確保兩個事件之間計時的周期準確性。顯然不能馬上列印,否則會影響時間
https://en.wikipedia.org/wiki/Hardware_performance_counter
如何從 C 獲取 x86_64 中的 CPU 周期數?
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/451476.html
上一篇:QtCustomCheckBox,關于PaintEvent的幫助
下一篇:什么是參考命令?
