簡體   English   中英

C++:為 std::vector 分配內存,然后並行初始化其元素

[英]C++: Allocate memory for an std::vector then initialize its elements in parallel

我有一個用例,用於創建一個包含許多元素的std::vector ,每個元素都是一個簡單但非原始的類型(POD 結構)。 向量和類型足夠大/復雜,在下面,

std::vector<U> v;
v.resize(1000000000);
for(size_t i=0;i<v.size();++i){/* initialize v[i] */}

resize調用明顯緩慢。 這很浪費,因為resize是默認初始化所有這些條目,然后我在循環中進行並將它們全部設置為正確/有用的值。

我想做的是為向量分配所有內存,但不初始化任何條目,然后並行執行並初始化所有條目,例如使用 OpenMP

std::vector<U> v;
v.reserve(1000000000);
#pragma omp parallel for
for(size_t i=0;i<v.size();++i){/* initialize v[i] */}

但是, reserve實際上並沒有改變v的大小,所以我必須在我的循環中繼續執行push_back ,這不會保持元素的正確順序(這在我的用例中很重要); 我真的很想在我的循環體中寫一些類似v[i] = ...東西。

有沒有辦法在不初始化任何元素的情況下分配/“初始化”一個向量,然后並行填充/初始化所有元素?

您的選擇是:

執行調整大小后,您可以按常規方式使用 OpenMP。

這取決於你的類型 U 的默認構造函數。如果默認構造函數很便宜,你就不太可能獲得並行化它的任何東西。

struct U {
   int a, b, c;
   U():a(0), b(1), c(2) {}
};

如果你的默認構造函數很昂貴,那么將它分成兩部分會更有意義:一個用於默認初始化,一個用於實際初始化的函數。

struct U {
   vector<int> a;
   U() {}
   void init(int n) { a.resize(n); }
};

在這兩種選擇中,對向量的常規調整大小或分配調用都很難被擊敗。

如果您確實打算以這種方式做事,則可以對數組使用 reinterpret_cast。 這樣,就不會調用默認構造函數。

U * u_array = reinterpret_cast<U*>(malloc(100*sizeof(U)));

我強烈建議不要使用最后一個選項。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM