CSDN 论坛 C/C++ 区的一个问题:对下面的代码,列出向量间的关系,并修改成并行程序:
for (i = 1; i <= 100; i = i + 1) { a[i] = b[i] + c[i]; b[i] = a[i] + d[i]; c[i+1] = a[i] + e[i]; }我的解法
还不确定这个问题的原始要求是否如下,以及这个解法是否正确,或有其它解法
推出的向量递推式如下:
初始时:
a[1] = b[1] + c[1];
递推式:
(1). a[i] = b[i] + a[i-1] + e[i-1]
(2). b[i] = sum_b(i) + c[1] + d[i] + sum_e(i-1)
(3). c[i+1] = sum_b(i) + c[1] +sum_e(i)
修改后的并发程序
这里使用 Windows 多线程并发的方式,用多进程也可
如果程序运行慢,请自行修改 GiveUpSchedule() 让渡调度函数
#include <stdio.h> #include <stdlib.h> #include <time.h> #include <iostream> #include <vector> #include <Windows.h> const int RANGE_MIN = 0; const int RANGE_MAX = 100; void PrintX(const char* name, const vector<int>& x); void CalculateOld(vector<int> a, vector<int> b, vector<int> c, vector<int> d, vector<int> e); void CalculateBreaker(vector<int> a, vector<int> b, vector<int> c, vector<int> d, vector<int> e); void test_02() { vector<int> a; vector<int> b; vector<int> c; vector<int> d; vector<int> e; int i; srand((unsigned int) time(NULL)); for (i = 0; i < 200; i++) { a.push_back((int) (((double) rand() / (double) RAND_MAX) * RANGE_MAX) + RANGE_MIN); b.push_back((int) (((double) rand() / (double) RAND_MAX) * RANGE_MAX) + RANGE_MIN); c.push_back((int) (((double) rand() / (double) RAND_MAX) * RANGE_MAX) + RANGE_MIN); d.push_back((int) (((double) rand() / (double) RAND_MAX) * RANGE_MAX) + RANGE_MIN); e.push_back((int) (((double) rand() / (double) RAND_MAX) * RANGE_MAX) + RANGE_MIN); } puts("\nArguments:"); PrintX("a[]", a); PrintX("b[]", b); PrintX("c[]", c); PrintX("d[]", d); PrintX("e[]", e); puts("\nThe old calculation:"); CalculateOld(a, b, c, d, e); puts("\nBreaker's calculation:"); CalculateBreaker(a, b, c, d, e); } void PrintX(const char* name, const vector<int>& x) { puts(name); for (int i = 1; i <= 101; i++) printf("%8d", x[i]); putchar('/n'); } // NOTE: increase arbitrary scheduling inline void GiveUpSchedule() { DWORD interval = (int) (((double) rand() / (double) RAND_MAX) * 500) + 50; Sleep(interval); } // shared among all threads class ConcurrentParam { public: vector<int>& a; vector<int>& b; vector<int>& c; vector<int>& d; vector<int>& e; ConcurrentParam(vector<int>& _a, vector<int>& _b, vector<int>& _c, vector<int>& _d, vector<int>& _e) : a(_a), b(_b), c(_c), d(_d), e(_e) {} }; DWORD WINAPI CalculateA(LPVOID param) { ConcurrentParam* cparam = (ConcurrentParam*) param; _ASSERT(cparam != NULL); // a[] for (int i = 2; i <= 100 ; i++) { GiveUpSchedule(); cparam->a[i] = cparam->b[i] + cparam->a[i-1] + cparam->e[i-1]; } return 0; } DWORD WINAPI CalculateBandC(LPVOID param) { ConcurrentParam* cparam = (ConcurrentParam*) param; _ASSERT(cparam != NULL); int i; int sum_b = 0, sum_e = 0; // b[] and c[] for (i = 1; i <= 100; i++) { GiveUpSchedule(); sum_b += cparam->b[i]; sum_e += cparam->e[i]; cparam->b[i] = sum_b + cparam->c[1] + cparam->d[i] + sum_e - cparam->e[i]; cparam->c[i + 1] = sum_b + cparam->c[1] + sum_e; } return 0; } void CalculateBreaker(vector<int> a, vector<int> b, vector<int> c, vector<int> d, vector<int> e) { DWORD ret; ConcurrentParam cparam(a, b, c, d, e); // CAUTION: a[1] MUST NOT in Parallel a[1] = b[1] + c[1]; // calculate simultaneously HANDLE hThreadA = CreateThread(NULL, 0, CalculateA, LPVOID (&cparam), 0, NULL); HANDLE hThreadBandC = CreateThread(NULL, 0, CalculateBandC, LPVOID (&cparam), 0, NULL); ret = WaitForSingleObject(hThreadA, INFINITE); ret |= WaitForSingleObject(hThreadBandC, INFINITE); _ASSERT(ret == WAIT_OBJECT_0); PrintX("a[]", a); PrintX("b[]", b); PrintX("c[]", c); } void CalculateOld(vector<int> a, vector<int> b, vector<int> c, vector<int> d, vector<int> e) { for (int i = 1; i <= 100; i++) { a[i] = b[i] + c[i]; b[i] = a[i] + d[i]; c[i + 1] = a[i] + e[i]; } PrintX("a[]", a); PrintX("b[]", b); PrintX("c[]", c); }