2013-03-11 27 views
8

我想實現一個像ThreadLocal一樣工作的CoreLocal映射,只有它返回一個特定於當前線程運行的核心的值。如何確定運行Java線程的內核?

原因是我想編寫代碼從隊列中取出作業,但我想優先考慮將其關聯數據與拾取從隊列中的工作。因此,我不希望整個程序有一個作業隊列,而是希望每個核心都有一個隊列,只有當隊列爲空時,工作線程纔會查看其他核心的隊列。

+3

https://github.com/peter-lawrey/Java-Thread-Affinity – bmargulies 2013-03-11 22:52:05

+2

Q ==隊列? :\ – 2013-03-11 22:52:12

+3

聽起來就像你在那裏的納秒時間真的很低。 – djechlin 2013-03-11 22:57:40

回答

0

也許你可以檢查/proc/[pid]/status

這些字段可能會有所幫助:

Cpus_allowed:CPU的面膜在此過程中可能會遇到

Cpus_allowed_list:同以前的,但在「名單格式「

1

有一個相關linux question沒有滿意的答案(解析top輸出不計數,接受的答案不再有效)。我認爲

/proc/<pid>/task/<tid>/sched 

可能給該信息在一條線上像

current_node=0, numa_group_id=0 

但上運行4.4.0-92-通用內核我i5-2400,該行始終是所有線程的相同。我想,「節點」意味着整個CPU(套接字),我只有一個。

我找不到這方面的文檔,或在this document中錯過了。


然而,恐怕這獲得這些信息可能難以相信幫助你:

  • 從proc文件系統讀數可以在你工作的規模過於昂貴。
  • ThreadLocal不同,您的CoreLocal不是線程安全的:將線程移植到另一個核心可能會破壞像someCoreLocalField++這樣的微不足道的非原子操作。暫停它也會這樣做。所以你需要一些原子或線程本地化來實現它,這可能會讓它變得太慢而不能滿足你的需求。
0

我不認爲有任何調用來獲取目前在JDK暴露了當前的CPU,但它肯定已經previously discussedproposed as a JDK enhancement

我認爲,直到類似的東西得到實施最好的辦法是使用類似JNA(簡單)或JNI(快)包本機的系統調用像getcpu在Linux或GetCurrentProcessorNumber在Windows上。

至少在Linux上,getcpu在VDSO中實現,沒有內核轉換,所以它應該只需要幾納秒,再加上幾個納秒的JNI調用。 JNA較慢。

如果你的確實是需要速度,你可以隨時添加函數作爲定製JVM的內在函數(因爲OpenJDK是開源的)。這將削減幾個納秒。

請記住,這些信息一旦得到就可能過時,所以您絕不應該依賴它來獲得性能,而只需要正確性。由於您已獲得「錯誤」值的支持,因此另一種可能的方法是將緩存的CPU ID值存儲在ThreadLocal中,並且只能定期更新。這使得緩慢的方法,例如解析/proc文件系統可行,因爲你很少做它們。爲了獲得最大速度,您可以定期從定時器線程中使線程本地無效,而不是檢查每個調用的失效條件。


兩者的討論和增強請求是高度推薦的讀數。

相關問題