2013-11-26 30 views
1

我優化了使用OpenMP循環。在每個線程中,一個大數組將被臨時使用(當這個線程完成時不需要)。由於我不想重複分配&刪除這些數組,所以我打算分配一大塊內存,併爲每個線程分配一部分。爲避免衝突,我應該爲每個正在運行的線程設置一個唯一的ID,該ID不應該改變,並且不能等於另一個線程。所以我的問題是,我可以通過函數omp_get_thread_num()爲此使用線程ID返回嗎?或者是否有任何有效的解決方案用於這種內存分配&分配任務?非常感謝!內存分配和分配在C++中使用OpenMP

+3

是的,可以。 omp_get_thread_num()返回不會改變的唯一線程ID,通常使用線程ID來分割矩陣/數組 –

+0

Cool!非常感謝! –

+0

您是否需要該內存才能在多個入口之間保持同一平行區域或連續並行區域?前一種情況的一個例子是具有平行內環的串行外環。同樣由'omp_get_thread_num()'**返回相同的線程ID並不一定表示代碼正在被同一進程線程執行。 –

回答

0

一旦你的程序遇到並行區域,即一旦它擊中

#pragma omp parallel 

線程(可能在程序初始化或直到第一個並行構造已啓動)將被激活。在並行區域內,任何分配內存的線程,例如數組,都將在它自己的私有地址空間內分配內存。除非線程解除分配內存,否則它將保持分配給整個並行區域。

如果您的程序首先以串行方式爲陣列分配內存,然後在進入並行區域時將該陣列複製到所有線程,請使用firstprivate子句並讓運行時間負責將陣列複製到每個線程的私有地址空間。

鑑於所有這一切,我沒有看到分配的點,大概在遇到並行區域之前,大量的內存然後使用一些自己的方法在線程之間共享它,以基於計算線程ID。

+0

謝謝。我的目的是爲了避免在線程中分配內存的開銷。假設線程大小爲8,並且每個線程都需要內存大小N,所以我只需要分配N * 8內存,並讓每個線程擁有唯一的大小爲N的私有部分。是的,我可以用firstprivate子句複製數組的指針,但是這不知道當前線程沒有使用哪個部分。 –

+1

啊,所以你寧願有一個線程分配'8n'字節,而不是'8'線程分配'n'字節。我不確定我認爲這不僅僅是一種不必要的優化 - 並且讓我相信,你不必向我展示數據。至於指針,你把他們帶入討論中,而不是我。 –

+0

其實,我想在開始的時候,而不是每個線程分配8N分配N,總的螺紋尺寸遠遠超過8個,但正處在同時運行最多8個線程。 –

2

可以啓動並行段,然後開始分配變量/記憶。在並行部分中聲明的所有內容在其自己的堆棧上都是線程私有的。例如:

#pragma omp parallel 
{ 
    // every variable declared here is thread private 
    int * temp_array_pointer = calloc(sizeof(int), num_elements); 
    int temp_array_on_stack[num_elements]; 

    #pragma omp for 
    for (...) { 
     // whatever my loop does 
    } 

    // if you used dynamic allocation 
    free(temp_array_pointer); 
} 
+0

你如何建議在這裏做錯誤處理?任何calloc調用都可能失敗。 IMO更容易在程序啓動時分配臨時結構,以便更輕鬆地處理錯誤。 – pburka

+2

@pburka如果你使用自動變量(堆棧分配),那麼你不需要錯誤處理。如果你在並行部分執行'* alloc',那麼你應該在這裏進行錯誤處理。我建議在parallel部分中分配所有線程專用的內容,以便1)避免任何潛在的錯誤,並在指針周圍傳遞2)如果你在NUMA機器上工作,那麼這將允許你分配內存硬件本地執行線程,從而提高性能。 –

+0

如果使用大自動變量,那麼應該熟悉'ulimit -s'(Un * x)/'/ STACK:nnn'(Windows)和'OMP_STACKSIZE'。 –