std::set
オブジェクトを設定し、C++で並列スレッドを使用してブール値ベクトルを編集できますか?並列スレッドを使用してセットにデータを書き込む際に危険がありますか?
私は並列計算に比較的新しく、OpenMPを使うことだけを学んでいます。読んでいる限り、スレッド間でデータ構造を共有してもいいと言う人がいると聞いてきました。
私の質問は、順序が重要でない限り、パラレルメソッドを使用していくつかのデータ構造を設定できますか?あるいは、あなたが一般的にそのようなことをしない理由は、単に注文が保存されないということだけです。ここで
は私がやろうとしていますものです:
input: std::vector<Object> u_set // vector containing universal set
int NUM_ELEMENTS = 1000;
std::set<int> my_set(); // set to be populated
std::vector<bool> my_bools(u_set.size(), false); // vector containing set membership information (true/false)
#pragma omp parallel for
for (int i = 0; i < NUM_ELEMENTS; ++i){
int next_el = get_next_element(); // next element from u_set
my_set.insert(next_el);
my_bools[next_el] = true;
}
コードは基本的にmemeberとして普遍集合から要素を選択し、サブセットにその値を追加し、ブールベクトルでそれをマークサブセット。これを並行して行うのは大丈夫ですか?それとも悪い形だと思われますか?このようなものが良いのでしょうか?
input: std::vector<Object> u_set // vector containing universal set
int NUM_ELEMENTS = 1000;
std::set<int> my_set(); // set to be populated
std::vector<bool> my_bools(u_set.size(), false); // vector containing set membership information (true/false)
int max_threads = omp_get_max_threads();
std::vector<std::vector<int> > elements(max_threads); // vector to contain data from each thread, so not accessing the same data structure
#pragma omp parallel for
for (int i = 0; i < NUM_ELEMENTS; ++i){
int next_el = get_next_element(); // next element from u_set
int curr_thread = omp_get_thread_num();
elements[curr_thread].push_back(next_el);
}
for (auto it = elements.begin(); it != elements.end(); ++it){
for (auto jt = elements[*it].begin(); jt != elements[*it].end(); ++it){
my_set.insert(*jt);
my_bools[*jt] = true;
}
}
これは、スレッドごとに別々のベクターを行い、その後、終了時にそれらを結合します。私はそれが技術的には同じデータ構造にまだアクセスしていることを知っていますが、私の考えでは、全体のデータ構造全体でベクトルを分離することで、混乱することからセキュリティレベルが向上します。
これを行うより良い方法ですか?または同じセットにアクセスしてアルゴリズムが進むにつれてそれに追加するのはいいですか?
短い答えは:いいえ。 'std :: set'はスレッドセーフではありません。 –
'const'メンバ関数だけが同時にアクセスできます。 http://en.cppreference.com/w/cpp/container#Thread_safetyを参照してください。 –
十分ですが、このコードを並列化するために提案できるものはありますか?第二の方法は安全でしょうか?同じベクトルでpush_backを呼び出さないためですか? – guskenny83