Я новичок в openmp, когда я добавляю openmp в свой код, я обнаружил, что результаты не одинаковы при разных запусках. это врожденная проблема openmp или проблема моего кода? Спасибо!
#include "stdafx.h"#include <iostream>
#include <vector>
#include <fstream>
#include <math.h>
#include<sstream>
#include <omp.h>
using namespace std;
int main()
{
double a[1000];
for (int i = 0; i < 1000; i++)
{
a[i] = 0;
}
for (int m = 0; m < 1000; m++)
{
#pragma omp parallel for shared(a)
for (int i = 0; i < 1000000; i++)
{
int b = pow(i, 0.5);
if (b < 1000)
{
//cout << i <<" "<<sin(i)<< endl;
a[b] += sin(i);
}
}
}
fstream all_temp;
all_temp.open("temperatureabcd.dat", fstream::out);
for (int aaa = 0; aaa < 1000; aaa++)
{
all_temp << a[aaa] << endl;
}
all_temp.close();
return 0;
}
Ваш код делает сокращение массива. Простое решение было бы сделать
#pragma omp parallel for reduction(+:a[:1000])
Однако MSVC, который вы используете (который я вывел из предварительно скомпилированного заголовка stdafx.h
) не поддерживает сокращение массива OpenMP. Вы можете сделать уменьшение массива вручную, немного изменив код
double a[1000] = {0};
for (int m = 0; m < 1000; m++) {
#pragma omp parallel
{
double a2[1000] = {0};
#pragma omp for nowait
for (int i = 0; i < 1000000; i++) {
int b = pow(i, 0.5);
if (b < 1000) a2[b] += sin(i);
}
#pragma omp critical
for(int i = 0; i < 1000; i++) a[i] += a2[i];
}
}
Другая проблема заключается в том, что сложение с плавающей точкой не является ассоциативным, поэтому порядок выполнения сокращения имеет значение. Это можно исправить с помощью немного больше работы, но это, вероятно, не ваша основная проблема.
Других решений пока нет …