OpenMPでのlockの初期化 [C/C++関連]
OpenMPをC++で使っているとクラスの仮想継承などで内部のメンバのomp_lock_t変数が初期化されているか確認することが必要になる。そうしないと複数回初期化されたりして嬉しくないことが起こる。
OpenMPでlockの初期化かされているかどうかを確認するAPIは用意されていない。
ただし、OpenMPのlockは所詮Mutexなので、omp_lock_tの中身を確認すれば、その判断をすることができるが、例えばIntelとGNUでomp_lock_tの中身は違う。
Intelはポインタ、GNUは4バイトのchar配列として取り扱われている。
個別のAPI毎に対応すれば初期化されているかどうかを確認することは出来なくもないが、
それはかなり面倒だし、確実ではない。
じゃあどうするかというと、こんな感じでやればとりあえずはできる。
ただし、このクラスは必ず並列化領域の前で最初にインスタンス化する必要がある。
staticメンバにすることによって仮想メモリ内で唯一となるので、
複数のスレッドから同一アドレスとなるので使う分には問題がなくなるはず。
ただし、デストラクタの時に開放はしないようにする。
このままだとメモリリークを起こすので、使わなくなった所で明示的にdeleteするぐらいしかなさそう。スマートじゃないのでもっといいやり方を考えてみる。
OpenMPでlockの初期化かされているかどうかを確認するAPIは用意されていない。
ただし、OpenMPのlockは所詮Mutexなので、omp_lock_tの中身を確認すれば、その判断をすることができるが、例えばIntelとGNUでomp_lock_tの中身は違う。
Intelはポインタ、GNUは4バイトのchar配列として取り扱われている。
個別のAPI毎に対応すれば初期化されているかどうかを確認することは出来なくもないが、
それはかなり面倒だし、確実ではない。
じゃあどうするかというと、こんな感じでやればとりあえずはできる。
ただし、このクラスは必ず並列化領域の前で最初にインスタンス化する必要がある。
staticメンバにすることによって仮想メモリ内で唯一となるので、
複数のスレッドから同一アドレスとなるので使う分には問題がなくなるはず。
ただし、デストラクタの時に開放はしないようにする。
Class A { public: A(); private: static omp_lock_t *m_pmutex; } omp_lock_t* A::m_pmutex == NULL; A::A(void) { if(m_pmutexForCout == NULL) { m_pmutex = new omp_lock_t; omp_init_lock(m_pmutex); } }
このままだとメモリリークを起こすので、使わなくなった所で明示的にdeleteするぐらいしかなさそう。スマートじゃないのでもっといいやり方を考えてみる。
コメント 0