-
Notifications
You must be signed in to change notification settings - Fork 0
/
workerthread.cpp
112 lines (103 loc) · 3.97 KB
/
workerthread.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
extern int precision;
#include <iostream>
#include "mandelbrot.hpp"
#include "workerthread.hpp"
uint64_t CalculatorParams::maxItr = 0;
int CalculatorParams::paddedDimX = 0;
uint64_t CalculatorParams::totalPoints = 0;
uint64_t CalculatorParams::pointsDone = 0;
extern int precision;
void WorkerThread(void *paramsPtr)
{
WorkerParams *params = (WorkerParams *)paramsPtr;
bool done = false;
bool down = false;
bool right = false;
std::vector<CalculatorParams *> *calcParamsVec;
mpf_class tmpBuf(0, precision);
mpz_class zr, zi, zrsqr, zisqr, bailout, cr, ci, one, tmp;
one = 1;
mpz_mul_2exp(one.get_mpz_t(), one.get_mpz_t(), precision);
bailout = 4;
mpz_mul_2exp(bailout.get_mpz_t(), bailout.get_mpz_t(), precision);
//mpf_class iSqr(0, precision), rSqr(0, precision), i(0, precision), r(0, precision), summie(0, precision);
std::unique_lock<std::mutex> queueLock(*params->dataMutex);
queueLock.unlock();
while(!done)
{
queueLock.lock();
if(params->workerThreadJobs->size() > 0)
{
std::list<std::vector<CalculatorParams *> *>::iterator prmItr = params->workerThreadJobs->begin();
calcParamsVec = *prmItr;
CalculatorParams::pointsDone += calcParamsVec->size();
std::cout << "Percentage done: " << (CalculatorParams::pointsDone * 100) / CalculatorParams::totalPoints << "%\n";
params->workerThreadJobs->erase(prmItr);
}
else
{
queueLock.unlock();
return;
}
queueLock.unlock();
if(calcParamsVec)
{
for(std::vector<CalculatorParams *>::iterator calcItr = calcParamsVec->begin(), calcEnd = calcParamsVec->end(); calcItr != calcEnd; calcItr++)
{
//Check if we've calculated this point before. If we have, it isn't 0
if(!*(*calcItr)->target)
{
// Now check the surrounding points to see if we need to calculate
int &offset = (*calcItr)->checkOffset;
if(offset)
{
// We know it's safe to look one step to the right, one step down and the combination.
// First look to the right.
uint64_t * checkPtr1 = (*calcItr)->target + offset;
down = false;
right = true;
// If not, check down from there
if(!*checkPtr1)
{
checkPtr1 += offset * CalculatorParams::paddedDimX;
down = true;
right = true;
}
// If not, it has to be left of that, 'cause it's not where we're standing.
if(!*checkPtr1)
{
checkPtr1 -= offset;
down = true;
right = false;
}
// Now we have a point. We also know where it was. This is important.
uint64_t * checkPtr2 = checkPtr1 + (right ? -1 : 1) * offset * 2;
uint64_t * checkPtr3 = checkPtr1 + (down ? -1 : 1) * offset * 2 * CalculatorParams::paddedDimX;
uint64_t * checkPtr4 = checkPtr3 + (right ? -1 : 1) * offset * 2;
// Finally, now that we have the four points, we need to compare them. Real quick and nasty: Xor them bitwise and see if we get 0.
// If we do, assign the same value to this point.
if( *checkPtr1 == *checkPtr2 &&
*checkPtr1 == *checkPtr3 &&
*checkPtr1 == *checkPtr4)
*(*calcItr)->target = *checkPtr1;
}
if(!*(*calcItr)->target)
{
cr = one;
ci = cr;
cr = (*calcItr)->point.r * cr;
ci = (*calcItr)->point.i * ci;
//std::cout << cr.get_str() << std::endl;
//std::cout << ci.get_str() << std::endl;
Mandelbrot::CountIterations(*(*calcItr)->target, cr, ci, CalculatorParams::maxItr, zr, zi, zrsqr, zisqr, bailout, tmp);
}
}
//std::cout << "Did iterations: " << *(*calcItr)->target << std::endl;
delete (*calcItr);
}
delete calcParamsVec;
}
}
std::cout << "Worker done, terminating.\n";
delete params;
}