2017-09-04 10 views
1

open_MPを使ってomp prallelを使ってみましたが、問題が発生しました。open_MPを使った静的変数thread_local

は、私は私の.cppファイルで空のベクターで初期化

class A { 
public: 
    static std::vector<double> v; 
} 

のように異なる静的クラスメンバーの多くを使用します。

は、いくつかの時間後、私はいくつかの計算を行い、最終的に私の初期値を持つベクトルv埋める:

A::v = {1,2,3}; 

いくつかの時間後、私はループのための大きなを持っている(ただし、してはならない)vの値を変更することができます再び。

は今、私は物事をスピードアップするためにopen_MPを使用しようとしました:

#pragma omp parallel for 
for (int i = 0; i < nsched; ++i) { 
    ... 
} 

私は、各ループは、静的なベクトルの独自のインスタンスを持つようにしたいので、私は単にそれをthread_local作ってみました。

class A { 
public: 
    static thread_local std::vector<double> v; 
} 

私の問題は今、できるだけ早く私は私のベクトルvはもはや{1,2,3}であるループの並列に入ると、それは単に空です。

どうすれば変更できますか?私は最初にvが "メインスレッド"のスレッドローカルであり、新しく作成された "子スレッド"がvに関する情報を得ないと仮定します 簡単にこの問題を解決する方法はありますか?または、スレッドごとにvを初期化する必要がありますか? (初期設定はかなりの時間がかかり、それがそう(しかし、可能性があるため、これは私がループの各パラメータを変更する必要がある)、素晴らしいことではないでしょう)

+0

私の謙虚な意見では、OpenMPでプログラムの並列部分を抽象化したいのであれば、TLSの使用を避けるべきです。ベクトルをプライベートとして宣言するのは簡単ではないでしょうか?あなたは本当にそれを民営化する必要がありますか?ベクトル要素へのアクセスがスレッドセーフである(つまり、ベクトルの要素数を変更しない)ことを保証する必要があるかもしれません。並列ループに関する情報は、あなたを助けるには十分ではありません。解決したい問題を理解できるように、[最小限の、完全で検証可能な]例(https://stackoverflow.com/help/mcve)を提供してください。 –

+0

また、[OpenMPとreduce on std :: vector](https://stackoverflow.com/a/43169193/5809597)を参照してください。 –

答えて

1

あなたが初期化を記述する場合

thread_local std::vector<double> A::v {1,2,3}; 

vのコピーはすべてのスレッドに{1,2,3}が含まれています。あなたは割り当て

A::v = {1,2,3}; 

を書く場合しかし、あなたはしません。 A::vは、スレッドごとに新たに初期化され、他のスレッドからはコピーされません。

配列のスレッドローカルコピーがいくつかの値のセットに初期化されている必要がある場合は、そこに値を格納するアクション(初期化または割り当て)が各スレッドで実行されていることを確認する必要があります。