Так что я довольно новичок в OpenMP, но недавно я начал играть с ним, и теперь я хочу использовать его, чтобы «ускорить» некоторые вычисления, которые мне нужно сделать.У меня есть функция, которая зависит от 3 переменных, и я хочу оценить ее в некоторых точках интервала, а затем показать значения в файле.Дело в том, что интервалы для 3-х параметров довольно большие, поэтому у меня будет много оценок функций.Использование 3-вложенного цикла for довольно сложно, если мой интервал большой.
Последовательная реализация прямолинейна, просто создайте 3-вложенный цикл, где каждый индекс i, j, k принимает значениесоответствующий параметр (целые числа от 1 до DIM и оценка функции в точке (i, j, k). В подходе OpenMP я, очевидно, думал об использовании #pragma omp parallel for
в надежде, что время выполнения программы будет быстрее.
Вот код, который я написал для последовательной реализации, и "параллельный". Пожалуйста, имейте в виду, что DIM установлен здесь на меньшее число только для целей тестирования.
#include <iostream>
#include <chrono>
#include <omp.h>
#include <cmath>
#include <fstream>
using namespace std;
ofstream outparallel("../output/outputParallel.dat");
ofstream outserial("../output/outputSerial.dat");
const int spaceDIM = 80;
double myFunction(double a, double b, double c)
{
return (double)a * log(b) + exp(a / b) + c;
}
void serialAlgorithmTripleLoop()
{
auto sum = 0;
auto timeStart = chrono::high_resolution_clock::now();
for (int i = 1; i <= spaceDIM; ++i)
for (int j = 1; j <= spaceDIM; ++j)
for (int k = 1; k <= spaceDIM; ++k)
{
//sum += i * j * k;
outserial << i << " " << j << " " << k << " " << myFunction((double)i, (double)j, (double)k) << endl;
}
auto timeStop = chrono::high_resolution_clock::now();
auto execTime = chrono::duration_cast<chrono::seconds>(timeStop - timeStart).count();
cout << "Serial execution time = " << execTime << " seconds";
cout << endl;
outserial << "Execution time = " << execTime << " seconds";
outserial << endl;
}
void parallelAlgorithmTripleLoop()
{
//start of the actual algorithm
auto sum = 0;
auto timeStart = chrono::high_resolution_clock::now();
#pragma omp parallel for
for (int i = 1; i <= spaceDIM; ++i)
for (int j = 1; j <= spaceDIM; ++j)
for (int k = 1; k <= spaceDIM; ++k)
{
// sum += i * j * k;
outparallel << i << " " << j << " " << myFunction((double)i, (double)j, (double)k) << endl;
}
auto timeStop = chrono::high_resolution_clock::now();
auto execTime = chrono::duration_cast<chrono::seconds>(timeStop - timeStart).count();
cout << "Parallel execution time = " << execTime << " seconds";
cout << endl;
outparallel << "Execution time = " << execTime << " seconds";
outparallel << endl;
}
int main()
{
cout << "FUNCTION OPTIMIZATION" << endl;
serialAlgorithmTripleLoop();
parallelAlgorithmTripleLoop();
return 0;
}
ВыводДля меня это неожиданно: используя параллельный подход, я получаю больше времени выполнения, чем последовательный. Я также пытался использовать предложения «сокращение» и «упорядоченный» и «свернутый» из стандарта OMP, но ни один из них не помог мне.на 4-ядерном 8-потоковом ноутбуке.
FUNCTION OPTIMIZATION
Serial execution time = 4 seconds
Parallel execution time = 7 seconds
В: Как правильно ускорить оценку функции?