簡體   English   中英

在 Thread.onSpinWait() 期間 CPU 使用率為 100%

[英]CPU usage is 100% during Thread.onSpinWait()

我正在為我的加密交易機器人編寫回測原始數據收集器,但遇到了一個奇怪的優化問題。

我經常在 Executors.newCachedThreadPool() 中有 30 個可運行對象,運行來自 API 的獲取請求。 由於 API 的請求限制為每分鍾 1200 個,因此我的可運行文件中有以下代碼:

    while (minuteRequests.get() >= 1170) {
        Thread.onSpinWait();
    }

是的,minuteRequests 是一個 AtomicInteger,所以我沒有遇到任何問題。

一切正常,問題是即使我使用推薦的忙等待 onSpinWait 方法,當啟動等待時,我的 CPU 使用率從 24% 左右上升到 100%。 作為參考,我在 3900X(24 線程)上運行它。

關於如何更好地處理這種情況的任何建議?

我的建議是不要忙着等待


Thread.onSpinWaitjavadocs是這樣說的:

表示調用者暫時無法繼續,直到其他活動發生一個或多個動作。 通過在自旋等待循環構造的每次迭代中調用此方法,調用線程向運行時指示它正忙於等待。 運行時可能會采取措施來提高調用自旋等待循環構造的性能

請注意,突出顯示的部分使用了單詞may而不是will 這意味着它也可能不會做任何事情。 此外,“提高性能”並不意味着您的代碼會客觀有效。

javadoc 還暗示改進可能取決於硬件。

簡而言之,這是使用onSpinwait的正確方法……但是您對它的期望太高了。 它不會使您的忙等待代碼高效。


那么我會建議你實際做什么呢?

我建議您將AtomicInteger替換為Semaphore ( javadoc )。 此特定循環將替換為以下內容:

semaphore.acquire();

這會阻止1直到 1 個“許可”可用並獲取它。 有關信號量如何工作的說明,請參閱 class javadocs。

注意:由於您沒有向我們展示您的速率限制的完整實現,因此不清楚您當前的方法實際上是如何工作的。 因此,我無法准確告訴您如何將AtomicInteger替換為Semaphore


1 - 被阻塞的線程被“停放”,直到其他線程釋放許可。 當它被停放時,線程不運行並且不與 CPU 內核相關聯。 內核要么處於空閑狀態(通常處於低功耗狀態),要么被分配給其他線程。 這通常由操作系統的線程調度程序處理。 當另一個線程釋放許可時, Semaphore.release方法將告訴操作系統解除在acquire中阻塞的線程之一。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM