2013-03-11 47 views
5

並行for循環我打算使用緩衝器std::vector<size_t> buffer(100),一個在每個線程在一個循環的一個並行化,作爲所建議的這樣的代碼:預分配的專用的std :: OpenMP中矢量在C++

std::vector<size_t> buffer(100); 
#pragma omp parallel for private(buffer) 
for(size_t j = 0; j < 10000; ++j) { 
    // ... code using the buffer ... 
} 

這代碼不起作用。儘管每個線程都有一個緩衝區,但它們的大小爲0.

如何在每個線程的開始處分配緩衝區?我仍然可以使用#pragma omp parallel for嗎?我能做到比這更優雅:

std::vector<size_t> buffer; 
#pragma omp parallel for private(buffer) 
for(size_t j = 0; j < 10000; ++j) { 
    if(buffer.size() != 100) { 
     #pragma omp critical 
     buffer.resize(100); 
    } 
    // ... code using the buffer ... 
} 
+0

我想我現在看到了這個問題。該向量未正確複製構建到OpenMP區域中。我不確定OpenMP標準中關於將'private'變量複製到線程中的說法。 – Mysticial 2013-03-11 22:28:44

+0

如果您希望它們分開,只需在OpenMP區域內聲明矢量即可。 – Mysticial 2013-03-11 22:29:43

+0

感謝您的澄清。如果我手動並行化循環,我知道如何去除OpenMP區域內的矢量。但是這也適用於'#pragma omp parallel for'嗎? – 2013-03-11 22:33:23

回答

7

斯普利特OpenMP的區域,如圖this question

然後在外部區域內但在for-loop本身之外聲明向量。這將爲每個線程創建一個本地向量。

#pragma omp parallel 
{ 
    std::vector<size_t> buffer(100); 

#pragma omp for 
    for(size_t j = 0; j < 10000; ++j) { 
    { 

     // ... code using the buffer ... 

    } 
} 
7

的問題和接受的答案已經存在了一段時間,這裏有一些更多的信息,其提供額外的洞察OpenMP和因此可能有助於給其他用戶。

在C++中,privatefirstprivate條款手柄類對象不同:

從OpenMP的應用程序接口V3.1:

私人:新的列表項被初始化,或有一個未定義的初始值,就像 已經在本地聲明沒有初始值。未指定調用類類型的不同私有變量的任何默認構造函數 的順序。

FIRSTPRIVATE:類類型的變量,一個拷貝構造函數被調用執行 初始化列表變量。

private調用默認構造函數,而firstprivate調用相應類的複製構造函數。

std::vector默認的構造函數構造一個沒有元素的空容器,這就是爲什麼有緩衝區大小爲0

要回答這個問題,這將是沒有需要分割的OpenMP區域的其他解決方案:

std::vector<size_t> buffer(100, 0); 
#pragma omp parallel for firstprivate(buffer) 
for (size_t j = 0; j < 10000; ++j) { 
    // use the buffer 
} 

編輯謹慎的關於一般私有變量一句話:線程堆棧大小是有限的,除非明確設置(環境變量OMP_STACKSIZE)編譯器相關的。如果你使用大容量內存的私有變量,堆棧溢出可能成爲一個問題。

+1

謝謝你。這正是我對物體和'private' /'firstprivate'所懷疑的。但是關於堆棧大小的說明,它完全不相關,因爲'std :: vector'在堆上分配內存,而實際的'vector'容器只需要在堆棧上存儲3個指針(在大多數實現中)。 – 2014-02-05 22:23:54

+0

這個答案更好,因爲它將'buffer'的拷貝數從10000減少到了線程數。 – chrisdembia 2015-05-16 04:03:02

+0

我可以做一些事情,例如先聲明一個向量數組,然後讓每個線程只訪問該數組的一個「插槽」中的向量?我已經完成了像int這樣的簡單變量,但是我並不確定用矢量做這件事是安全的。 – 2015-11-25 17:18:37