Я новичок в OpenMP и пытаюсь распараллелить следующий цикл for
, который включает в себя 2 внутренних цикла for
.При помощи 2-го внутреннего цикла в зависимости от результата 1-го.
После прочтения следующего ответа я распараллелил внешний цикл.
Теперь я бы хотел распараллелить 2 внутренних цикла .Чтобы заняться этим, я подумал о том, чтобы их вложить.
Меня беспокоит условия гонки , которые могут возникнуть.Я читал об объявлении private vars
.Это способ избежать этой проблемы?
Еще один момент, который меня беспокоит, это то, что я инициализировал большинство своих переменных вне внешнего цикла for
.После комментариев к комментариям по этой теме Я подумал, что должен указать на это.
#include <iostream>
#include <cstring>
#include <vector>
#include <string>
#include <random>
#include <algorithm>
#include <omp.h>
int main(int argc, const char *argv[]) {
const int N = 1000000;
const double T = 1;
const int r = 0;
const int K = 100;
const double s = 0.5;
const int S0 = 100;
const int m = 1000;
const double k=0.9;
const double D = T / m;
std::vector<double> A;
std::vector<double> kappa(21, 0);
std::vector<double> U(21, 0);
const double distMean = (r - pow (s, 2.0) / 2) * D;
const double distStdDev = s * pow(D, 0.5);
const int distSize = 1000;
#pragma omp parallel for num_threads(8)
for (int i = N; i > 0; --i) {
std::random_device randDev; //print this one separately
std::mt19937 generator(randDev());
std::normal_distribution<double> dist(distMean, distStdDev);
std::vector<double> X;
X.reserve(distSize + 1);
#pragma omp parallel for //num_threads(8)
for (int m = distSize; m > 0; --m) {
X.push_back(dist(generator));
}
std::vector<double> XCumSum(1000);
std::partial_sum(X.begin(), X.end(), XCumSum.begin(), std::plus<double>());
std::vector<double> expCumSum;
expCumSum.reserve(distSize + 1);
for (int m = distSize; m > 0; --m) {
expCumSum.push_back( exp( XCumSum[m] ) );
}
double maxPart2 = k * S0 * ( std::accumulate(expCumSum.begin(), expCumSum.end(), 0.0) / expCumSum.size() ) ;
double maxPart1 = S0 * exp(std::accumulate(X.begin(), X.end(), 0.0));
double result = exp(-r*T) * std::max( (maxPart1 - maxPart2), 0.0 );
A.reserve(N + 1);
A.push_back(result);
}
float ASumMean = ( std::accumulate(A.begin(), A.end(), 0.0) ) / A.size();
std::cout << ASumMean << std::endl;
return ASumMean;
}
Я компилирую это с
g++-8.2 -O3 -o tests tests.cpp
Безfopenmp
мои результаты:
16.6318
real 1m27.113s
user 1m14.483s
sys 0m11.217s
С fopenmp
, с использованием g++-8.2 -O3 -o tests tests.cpp -fopenmp
, и результаты:
16.6555
real 0m39.474s
user 1m42.468s
sys 0m30.546s
Это ожидаемые результаты, но время иУскорение, заставьте меня усомниться в фактическом кодировании цикла.
PS: довольно плохо знаком с C ++.Всегда приветствуются любые предложения о том, как улучшить мой стиль, или советы по передовому опыту.