2014-04-02 63 views
0

在此應用程序中,我有N個(POSIX)線程組。第一組啓動,創建一個對象A,然後放下。稍後,一個帶有N個線程的新組啓動,使用A創建一個類似的對象B並放棄。這種模式重複。該應用程序需要大量內存(A和B有大量的malloc'ed數組)。我希望儘可能地訪問本地內存。我可以使用numactl --localalloc來實現此目的,但爲了實現此目的,我還需要確保來自第一組和第二組的同一數據上的那些線程綁定到相同的NUMA節點。我查看了sched_setaffinity,但不知道是否有更好的方法存在。將後續線程組中的兩個線程綁定到同一個內核

該應用程序的邏輯是這樣的,一個沒有單獨的線程組的解決方案會撕裂程序邏輯。也就是說,一組線程管理第一個對象A和後來的對象B(沒有在兩者之間徘徊)是一個極其複雜的解決方案,並且消除了面向對象的代碼佈局。

回答

1

將B組中的線程綁定到它們在組A上運行的相同內核比您需要的更具限制性。現代處理器對每個內核使用專用的1級緩存(L1)和2級緩存(L2),因此將線程綁定到特定內核只有在數據在這些緩存中仍然「熱」時纔有意義。你可能意味着將B組線程綁定到與A組中的線程相同的numa節點,以便大型數組位於同一個本地內存中。

這就是說,你有兩個選擇:

  1. 你A組的關係設置一個特定的NUMA節點,並使用相同的NUMA節點設置B組的親和力,或
  2. 您可以找出您的malloc'ed數組所在的numa節點,並將組B的親和性設置爲該numa節點。

選項(1)比較容易,所以我們來談談如何實現選項(2)。

以下SO回答描述瞭如何找出來,給定一個虛擬地址在你的過程,NUMA節點有本地的內存:

Can I get the NUMA node from a pointer address (in C on Linux)?

有一個在-lnuma的move_pages功能: http://linux.die.net/man/2/move_pages它可以將地址(頁面)的當前狀態報告給節點映射:

節點也可以爲NULL,在這種情況下,move_pages()不移動任何頁面,而是返回每個頁面當前所在的節點,狀態陣列。獲取每個頁面的狀態可能是確定需要移動的頁面所必需的。

武裝與信息,你想你B組線程的親和力設置爲NUMA節點,怎麼做,我們去這個SO回答

How to ensure that std::thread are created in multi core?

爲在FreeBSD cpuset_setaffinity()中,在Windows SetThreadAffinityMask()等中需要使用POSIX線程的GNU/linux。

+0

謝謝 - 絕對意思是numa節點,w有點草率,不熟悉術語。非常有用的信息。恐怕我只需要1) - 所以我應該去sched_setaffinity - 是否正確?我擔心將有關可用CPU集的信息傳遞給該程序 - 這似乎是一個必要的要求。我已經尋找了一種方法來自動確定可用於程序的CPU集合(如果有意義的話)(以便每個線程知道它需要綁定的CPU集合)。這是可能的,還是不正確的問題? – micans

+0

另一種可能性是在進程啓動之前將進程中的線程限制到特定節點。除了'numactl --localalloc'向本地節點請求內存以外,還將確保您的組A和B中的線程始終運行在內存爲本地的節點中。你可以用'--cpunodebind'選項來做到這一點。請注意,通過這樣做,您將應用程序限制爲單個節點,因此,如果您的應用程序是該節點上唯一的應用程序,並且程序不會從更多線程中受益,那麼這是一個勝利。 – amdn

+0

一些很好的閱讀:https://access.redhat.com/site/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/Performance_Tuning_Guide/main-cpu.html – amdn

相關問題