Я хочу распараллелить некоторые циклы и широко использовать openMP в других частях кода. Есть объект, который я хочу использовать внутри al oop, который имеет некоторое резервное хранилище (должно быть общим для всех потоков) и некоторое состояние (должно быть приватным для каждого потока).
Представьте себе что-то вроде:
class P {
public:
// fills storage with 0, 1, 2...
P(size_t something) {
for(size_t i = 0; i < something; i++)
m_storage.push_back(i);
}
// finds the closest value in m_storage to probe
// the algorithm is a stupid dummy, but gets the point across
float findClosest(float probe) {
m_state = std::numeric_limits<float>::max();
auto closest = std::numeric_limits<float>::quiet_NaN();
for(const auto x: m_storage)
if(m_state > probe - x) {
closest = x;
m_state = probe - x;
}
return closest;
}
private:
std::vector<float> m_storage;
float m_state;
}
// sequential access
int main(){
P p = new P(100);
std::vector<float> results(5);
for(size_t i = 0; i<5; i++) {
results[i] = p.findClosest(i);
}
}
// parallel access with copy => p.m_storage is copied
int main(){
P p = new P(100);
std::vector<float> results(5);
#pragma omp parallel for firstprivate(p)
for(size_t i = 0; i<5; i++) {
results[i] = p.findClosest(i);
}
}
// parallel access with share => p.m_state is altered by multiple threads
int main(){
P p = new P(100);
std::vector<float> results(5);
#pragma omp parallel for firstprivate(p)
for(size_t i = 0; i<5; i++) {
results[i] = p.findClosest(i);
}
}
Так что либо я трачу много памяти и кеша, либо реализация прерывается из-за совместного использования переменной.
Я думаю, что не могу пометить части общего объекта, а другие как частные или что-нибудь подобное Объект довольно сложный, и состояние используется в разных местах. Есть ли какой-нибудь волшебный c способ заставить объект совместно использовать свое хранилище, но иметь состояние для объекта?
например что-то вроде
[...]
private:
#pragma omp parallel shared
std::vector<float> m_storage;
#pragma omp parallel private
float m_state;