私のプログラムでOpenMPを使用しようとしています(私はOpenMPを使用している初心者です)。プログラムは2つの場所でエラーを返します。ここでOpenMPを使用したポインタ
はサンプルコードです:
#include <iostream>
#include <cstdint>
#include <vector>
#include <boost/multi_array.hpp>
#include <omp.h>
class CNachbarn {
public:
CNachbarn() { a = 0; }
uint32_t Get_Next_Neighbor() { return a++; }
private:
uint32_t a;
};
class CNetwork {
public:
CNetwork (uint32_t num_elements_);
~CNetwork();
void Validity();
void Clean();
private:
uint32_t num_elements;
uint32_t nachbar;
std::vector<uint32_t> remove_node_v;
CNachbarn *Nachbar;
};
CNetwork::CNetwork(uint32_t num_elements_ ) {
num_elements = num_elements_;
Nachbar = new CNachbarn();
remove_node_v.reserve(num_elements);
}
CNetwork::~CNetwork() {
delete Nachbar;
}
inline void CNetwork::Validity() {
#pragma omp parallel for
for (uint32_t i = 0 ; i < num_elements ; i++) {
#pragma omp critical
remove_node_v.push_back(i);
}
}
void CNetwork::Clean() {
#pragma omp parallel for
for (uint8_t j = 0 ; j < 2 ; j++) {
nachbar = Nachbar->Get_Next_Neighbor();
std::cout << "i: " << i << ", neighbor: " << nachbar << std::endl;
}
remove_node_v.clear();
}
int main() {
uint32_t num_elements = 1u << 3;
uint32_t i = 0;
CNetwork Network(num_elements);
do {
Network.Validity();
Network.Clean();
} while (++i < 2);
return 0;
}
私はの#pragmaが重要OMP場合
を知っていただきたいと思い
push_back()
に適したソリューションですか? (この問題は解決しますか?)スレッドごとに独自のベクトルを定義し、それらを結合する方がよいでしょうか?または何らかの種類のlock
?私の元のコードでは、実行中のエラー:
nachbar = Nachbar->Get_Next_Neighbor(&remove_node_v[i]);
が表示されますが、この例では表示されません。私はOpenMPがCNachbarn
コアの数として使用することを望んでいます。CNachbarn
は再帰的な計算であり、他のスレッドの影響を受けてはならないからです。問題はそれをいかにスマートにするかです。 (私は私が私のシミュレーションと時間で百万回以上この関数を呼び出すので、私は、forループを開始するたびに重要であるCNachbarn
を定義するために、スマートであると思ういけない
以下のような各スレッドの配列の要素は、問題を示す*最小限の例を投稿してください。あなたは私たちにすべての仕事をここにロードしています。 –
1.ここにベクターが本当に必要ですか?その配列をmemsetにある種の "無効な"値を導入することが可能な場合、単純な配列を使ってクリティカルセクションを削除することができるようです。この配列をスキャンして、無効でないすべての値をベクターにプッシュできます。タスクのサイズによっては大幅に増強することもあれば増やすこともできませんが、時間のかかるループではなくOMPを使用することはできません。 –
@ Konrad、私は実例をアップロードしました – Eagle