我正在開發low level routines for binary search in C和x64程序集,並嘗試測量未緩存陣列(RAM中的數據)搜索的確切執行時間。根據分支預測的「幸運」程度,搜索同一個陣列以獲得不同的目標會花費大量不同的時間。我可以準確地測量最短執行時間和中間執行時間,但我發現很難衡量最大執行時間。用RDTSC精確測量最大週期數
問題是分支預測的最壞情況在時間上可以與平均情況加上處理器中斷相比較。最糟糕的情況和中斷都很少見,但我還沒有想出一個很好的方法來區分一個罕見事件和另一個罕見事件。標準方法是簡單地過濾掉所有「異常」的高測量值,但只有在兩者之間有清晰的線條時才能使用。
所以現在的問題變成,「我怎樣才能被中斷的測量和一個合法花更長的時間比其他地區之間的區別?」
或者更一般地說,「如何衡量全執行時間的分佈,而不會事先假設一個硬性最大值?「
內核是否存儲我可以查詢是否發生中斷的任何信息?在測量之前和之後我可以查詢哪些信息,這些信息會告訴我測量是否被中斷?理想情況下,它會告訴我中斷髮生的週期有多長,但只知道測量受到影響將是一個很好的開始。
也許除了(或不是)RDTSC之外,我可以使用RDPMC讀取一個計數器來測量Ring 0(內核)而不是Ring 3(用戶)所花費的週期數?是否有可能已經設立了櫃檯來做到這一點,或者我需要建立自己的櫃檯?我是否需要創建自己的內核模塊來執行此操作,還是可以使用現有的ioctls?
一些背景資料:
我運行主要是在英特爾SKYLAKE微架構i7-6700運行Ubuntu Linux的14.03 4.2.0,但我還測試了英特爾的Sandy Bridge和Haswell的。我已盡最大努力盡可能減少系統抖動。我已經使用CONFIG_NOHZ_FULL重新編譯了一個無tickless內核,沒有強制搶佔,支持透明的巨大頁面支持,並且定時器頻率爲100 Hz。
我停止了大部分不必要的進程,並刪除了大部分不必要的內核模塊。我使用cpuset/cset shield來爲單個進程保留一個NoHZ內核,並使用內核/調試/跟蹤來驗證我得到的中斷很少。但我仍然剛剛夠準確的測量是困難的。也許更重要的是,我可以設想未來的長尾情況(一個很少需要調整大小的散列表),它能夠區分有效和無效的測量將是非常有幫助的
我正在測量執行時間與RDTSC/RDTSCP使用Intel suggests in their whitepaper的技術,並且通常會獲得我期望的精度。我的測試涉及到搜索16位值,並且我在可變長度的隨機數組上重複單獨計時65536次搜索。爲了防止處理器學習正確的分支預測,每次都以不同的順序重複搜索。每次使用「CLFLUSH」搜索後,搜索的數組將從緩存中刪除。
這是一個研究項目,我的目標是瞭解這些問題。因此,我願意接近那可能被認爲是愚蠢和極端的事情。定製內核模塊,保護模式x64程序集,未經測試的內核修改以及處理器特定的功能都是公平的遊戲。如果有辦法擺脫少數剩餘的中斷,以便所有的測量都是「真實的」,那麼這也可能是一個可行的解決方案。感謝您的建議!
我不能說出你的問題是什麼。所有的細節都沒有增加清晰度。 – Jeff
嗨傑夫 - 對不起,如果我沒有清晰。問題是粗體的兩部分。我正在尋找一種方法來追溯確定在RDTSC測量期間處理器是否被中斷。對於後臺,考慮這個線程:https://software.intel.com/en-us/forums/software-tuning-performance-optimization-platform-monitoring/topic/405642其中帕特里克說:「請注意,在ring3(用戶土地),你也可能會在你的代碼中間出現中斷,這可能會讓你的計數變得糟糕。「我想弄清楚如何確定發生的時間。 –
你可以禁用中斷嗎? – Jeff