[英]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] = ...
東西。
有沒有辦法在不初始化任何元素的情況下分配/“初始化”一個向量,然后並行填充/初始化所有元素?
您的選擇是:
std::vector
執行調整大小后,您可以按常規方式使用 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.