我想實現一個像ThreadLocal一樣工作的CoreLocal映射,只有它返回一個特定於當前線程運行的核心的值。如何確定運行Java線程的內核?
原因是我想編寫代碼從隊列中取出作業,但我想優先考慮將其關聯數據與拾取從隊列中的工作。因此,我不希望整個程序有一個作業隊列,而是希望每個核心都有一個隊列,只有當隊列爲空時,工作線程纔會查看其他核心的隊列。
我想實現一個像ThreadLocal一樣工作的CoreLocal映射,只有它返回一個特定於當前線程運行的核心的值。如何確定運行Java線程的內核?
原因是我想編寫代碼從隊列中取出作業,但我想優先考慮將其關聯數據與拾取從隊列中的工作。因此,我不希望整個程序有一個作業隊列,而是希望每個核心都有一個隊列,只有當隊列爲空時,工作線程纔會查看其他核心的隊列。
也許你可以檢查/proc/[pid]/status
這些字段可能會有所幫助:
Cpus_allowed:CPU的面膜在此過程中可能會遇到
Cpus_allowed_list:同以前的,但在「名單格式「
有一個相關linux question沒有滿意的答案(解析top
輸出不計數,接受的答案不再有效)。我認爲
/proc/<pid>/task/<tid>/sched
可能給該信息在一條線上像
current_node=0, numa_group_id=0
但上運行4.4.0-92-通用內核我i5-2400,該行始終是所有線程的相同。我想,「節點」意味着整個CPU(套接字),我只有一個。
我找不到這方面的文檔,或在this document中錯過了。
然而,恐怕這獲得這些信息可能難以相信幫助你:
ThreadLocal
不同,您的CoreLocal
不是線程安全的:將線程移植到另一個核心可能會破壞像someCoreLocalField++
這樣的微不足道的非原子操作。暫停它也會這樣做。所以你需要一些原子或線程本地化來實現它,這可能會讓它變得太慢而不能滿足你的需求。我不認爲有任何調用來獲取目前在JDK暴露了當前的CPU,但它肯定已經previously discussed 和proposed as a JDK enhancement。
我認爲,直到類似的東西得到實施最好的辦法是使用類似JNA(簡單)或JNI(快)包本機的系統調用像getcpu
在Linux或GetCurrentProcessorNumber
在Windows上。
至少在Linux上,getcpu
在VDSO中實現,沒有內核轉換,所以它應該只需要幾納秒,再加上幾個納秒的JNI調用。 JNA較慢。
如果你的確實是需要速度,你可以隨時添加函數作爲定製JVM的內在函數(因爲OpenJDK是開源的)。這將削減幾個納秒。
請記住,這些信息一旦得到就可能過時,所以您絕不應該依賴它來獲得性能,而只需要正確性。由於您已獲得「錯誤」值的支持,因此另一種可能的方法是將緩存的CPU ID值存儲在ThreadLocal
中,並且只能定期更新。這使得緩慢的方法,例如解析/proc
文件系統可行,因爲你很少做它們。爲了獲得最大速度,您可以定期從定時器線程中使線程本地無效,而不是檢查每個調用的失效條件。
兩者的討論和增強請求是高度推薦的讀數。
https://github.com/peter-lawrey/Java-Thread-Affinity – bmargulies 2013-03-11 22:52:05
Q ==隊列? :\ – 2013-03-11 22:52:12
聽起來就像你在那裏的納秒時間真的很低。 – djechlin 2013-03-11 22:57:40