我正在尝试使用 opemMP 制作“谐波级数和”问题的并行版本。 但根据输入的不同,输出也不同。 (并行和顺序)
程序:
#include "stdafx.h"
#include <iostream>
#include <sstream>
#include <omp.h>
#include <time.h>
#define d 10 //Numbers of Digits (Example: 5 => 0,xxxxx)
#define n 1000 //Value of N (Example: 5 => 1/1 + 1/2 + 1/3 + 1/4 + 1/5)
using namespace std;
void HPSSeguencial(char* output) {
long unsigned int digits[d + 11];
for (int digit = 0; digit < d + 11; ++digit)
digits[digit] = 0;
for (int i = 1; i <= n; ++i) {
long unsigned int remainder = 1;
for (long unsigned int digit = 0; digit < d + 11 && remainder; ++digit) {
long unsigned int div = remainder / i;
long unsigned int mod = remainder % i;
digits[digit] += div;
remainder = mod * 10;
}
}
for (int i = d + 11 - 1; i > 0; --i) {
digits[i - 1] += digits[i] / 10;
digits[i] %= 10;
}
if (digits[d + 1] >= 5) {
++digits[d];
}
for (int i = d; i > 0; --i) {
digits[i - 1] += digits[i] / 10;
digits[i] %= 10;
}
stringstream stringstreamA;
stringstreamA << digits[0] << ",";
for (int i = 1; i <= d; ++i) {
stringstreamA << digits[i];
}
string stringA = stringstreamA.str();
stringA.copy(output, stringA.size());
}
void HPSParallel(char* output) {
long unsigned int digits[d + 11];
for (int digit = 0; digit < d + 11; ++digit)
digits[digit] = 0;
int i;
long unsigned int digit;
long unsigned int remainder;
#pragma omp parallel for private(i, remainder, digit)
for (i = 1; i <= n; ++i) {
remainder = 1;
for (digit = 0; digit < d + 11 && remainder; ++digit) {
long unsigned int div = remainder / i;
long unsigned int mod = remainder % i;
digits[digit] += div;
remainder = mod * 10;
}
}
for (int i = d + 11 - 1; i > 0; --i) {
digits[i - 1] += digits[i] / 10;
digits[i] %= 10;
}
if (digits[d + 1] >= 5) {
++digits[d];
}
for (int i = d; i > 0; --i) {
digits[i - 1] += digits[i] / 10;
digits[i] %= 10;
}
stringstream stringstreamA;
stringstreamA << digits[0] << ",";
for (int i = 1; i <= d; ++i) {
stringstreamA << digits[i];
}
string stringA = stringstreamA.str();
stringA.copy(output, stringA.size());
}
int main() {
//Sequential Method
cout << "Sequential Method: " << endl;
char outputSeguencial[d + 10];
HPSSeguencial(outputSeguencial);
cout << outputSeguencial << endl;
//Cleaning vector
string stringA = "";
stringA.copy(outputSeguencial, stringA.size());
//Parallel Method
cout << "Parallel Method: " << endl;
char outputParallel[d + 10];
HPSParallel(outputParallel);
cout << outputParallel << endl;
system("PAUSE");
return 0;
}
示例:
输入:
#define d 10
#define n 1000
输出:
Sequential Method:
7,4854708606╠╠╠╠╠╠╠╠╠╠╠╠
Parallel Method:
6,6631705861╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ÇJ^
输入:
#define d 12
#define n 7
输出:
Sequential Method:
2,592857142857╠╠╠╠╠╠╠╠╠╠╠╠╠╠ÀÂ♂ü─¨@
Parallel Method:
2,592857142857╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ÇJJ
问候
粘贴代码
最佳答案
在更新 digits
数组时,你们的线程会互相踩踏。因此,一些添加内容会丢失,并且您会得到虚假结果(几乎可以肯定,不同的运行会产生不同的结果)。
您必须将写入同步到数字
,例如具有原子(或关键)部分:
// ... <snip>
#pragma omp parallel for private(i, remainder, digit)
for (i = 1; i <= n; ++i) {
remainder = 1;
for (digit = 0; digit < d + 11 && remainder; ++digit) {
long unsigned int div = remainder / i;
long unsigned int mod = remainder % i;
#pragma omp atomic // <- HERE, could also be #pragma omp critical
digits[digit] += div;
remainder = mod * 10;
}
}
// <snip> ...
这样一次只有一个线程可以更新数组。不过,对于这样的任务,这可能会抵消将任务拆分为多个线程的任何 yield 。
关于c++ - 谐波级数和 c++ openMP,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13387900/