2014-05-21 133 views
3

我正在寫一個使用密集型CPU和內存使用情況的多線程Java程序。 該程序的目標是在圖上執行一些算法。該程序在運行linux的NUMA機器上執行,我希望獲得最佳性能。NUMA體系結構的有效使用

爲此,我爲每個NUMA節點製作一些圖的副本,以便每個線程都能夠訪問本地存儲器上的圖。

本地內存分配的一部分已經通過在分配圖的每個新副本之前設置相關性來完成。這是通過jna完成的,所以我寧願留在這個庫中,也不要添加jni代碼,如果可能的話。

我的問題是我如何檢查工作線程運行在哪個內核上,以便從本地內存中讀取數據?

我知道在執行期間線程與核心的綁定可能會發生變化。但是,內核嘗試在所有時間片上的同一個NUMA節點上運行線程。因此,只有在開始時,檢查線程運行在哪個內核上才能適用於大多數情況。

+2

這是相當困難的事情,即使在C/C++,由於質量差/支持NUMA庫。 – Mysticial

+0

我不需要專門的NUMA庫。只是想知道線程運行在哪個內核上。從核心ID我可以知道NUMA節點沒有問題。 – jutky

+0

我非常懷疑你可以用Java來做到這一點。唯一真正的選擇是C++(我自己是一名Java開發人員)。但是對於NUMA體系結構和並行處理,C++和MPI是唯一的選擇。 – Alexandros

回答

3

事實證明,有就是通過調用JNA以獲得所需的信息的方法。 方法名是:sched_getcpu。而完整的代碼片段看起來是這樣的

public interface CLibrary extends Library{ 
    public static final CLibrary INSTANCE = 
      (CLibrary) Native.loadLibrary("c", CLibrary.class); 
    public int sched_getcpu() throws LastErrorException; 
} 

現在,當你

CLibrary.INSTANCE.sched_getcpu(); 

你得到的核心ID,在當前線程運行。

0

你在說什麼是線程關聯。也許這會有所幫助。

Java thread affinity

你需要的,如果不覆蓋它是使用原生代碼來找出哪些核心是其NUMA做其他的事情。

+0

我已經使用線程關聯來爲每個NUMA節點上的圖形創建本地副本(如問題所述)。在啓動階段,我可以使用線程關聯來運行。但我不想將整個並行算法限制在特定的內核中。我依賴於比I更好的負載平衡的操作系統。關於您的「本地代碼」部分回答 - 那是什麼問題。 – jutky

1

我發現,要完成上述任務的最簡單的方法是運行shell命令和解析輸出。

既然我知道進程的ID和當前線程的線程ID(與JNA實現的),我運行以下命令:

ps -p <pid> -L -o tid,psr | grep <tid> 

結果是雙號線,第一個是線程ID,第二個是該線程正在執行的核心ID。

在一個循環中,我設置該線程的親和性不同的核,並檢查了上述命令的輸出。輸出總是正確的。