I am trying Pthreads and its pretty basic program: I have two shared variables (declared global) among all threads
long Sum = 0;
long Sum1 = 0;
pthread_mutex_t mutexLock = PTHREAD_MUTEX_INITIALIZER;
In thread function:
for(int i=start; i<end; i++) //start and end are being passed to thread and they are being passed correctly
{
pthread_mutex_lock(&mutexLock);
Sum1+=i;
Sum+=Sum1;
pthread_mutex_unlock(&mutexLock);
}
main() in case one needs for reference:
int main()
{
pthread_t threadID[10];
for(int i=0; i<10; i++)
{
int a = (i*500) + 1;
int b =(i + 1)*500;
ThreadStruct* obj = new ThreadStruct(a,b);
pthread_create(&threadID[i],NULL,ThreadFunc,obj);
}
for(int i=0; i<10; i++)
{
pthread_join(threadID[i], NULL);
}
cout<<"Sum: "<<Sum<<endl;
cout<<"Sum1: "<<Sum1<<endl;
return 0;
}
OUTPUT
Sum: 40220835000
Sum1: 12502500
Run again
Sum: 38720835000
Sum1: 12502500
Run again
Sum: 39720835000
Sum1: 12502500
PROBLEM
Why I am getting a different value for Sum in each iteration?
Rest whole code is working ok and output of Sum1 is correct - no matter how much times do I run the code. (Only issue is in Sum). Am I doing something wrong in use of mutex here?
UPDATE
If I use local variables as #molbdnilo specified in his well detailed answer, this problem is solved. In start, I thought that mutex is irrelevant here but I tested it a number of times and observed the cases when not using a mutex results in recurrence of this problem. So, solution of this problem (courtesy: Answer by #molbdnilo) is to use local variables WITH mutex and I have tested it to work perfectly!
It's not a threading problem – the problem is that even though the order of additions to Sum1 doesn't matter, the order of additions to Sum does.
Consider the much shorter sum 1 + 2 + 3 and the following interleavings
1:
Sum1 = 1 + 2 = 3
Sum = 0 + 3 = 3
Sum1 = 3 + 3 = 6
Sum = 3 + 6 = 9
2:
Sum1 = 1 + 3 = 4
Sum = 0 + 4 = 4
Sum1 = 4 + 2 = 6
Sum = 4 + 6 = 10
3:
Sum1 = 2 + 3 = 5
Sum = 0 + 5 = 5
Sum1 = 5 + 1 = 6
Sum = 5 + 6 = 11
You could solve this by having the threads compute their own sum-of-sums independently and adding them afterwards.
(Notice that there's no concurrent mutation here, so locking anything can't make any difference.)
For a more concrete example, let's limit your program to two threads and the sum from 1 to 6.
You then have one thread computing 1 + 2 + 3 and one doing 4 + 5 + 6.
At a glance, thread one should also compute 1 + (1 + 2) + (1 + 2 + 3) and thread 2, 4 + (4 + 5) + (4 + 5 + 6).
Except they don't – every time they use it, Sum may have been modified by the other thread.
So thread one may compute 1 + ((1 + 4) + 2) + ((1 + 4) + 2 + 3), or something else.
When you use local variables, you keep each thread's result independent of the others.
(I think this problem is a pretty good illustration of how shared mutable state can complicate things in unexpected ways, by the way.)
Related
I am trying to Parallelize DES but hardly getting any speedup. Parallelizing the s-box part is not giving any speed up rather it is running in polynomial time.
Here is the s-box part of the DES:
int row[8],col[8],val[8];
//s box parallelism
#pragma omp parallel for num_threads(8) schedule(static)
for (int i = 0; i < 8; i++) {
//the value of '0' is 48, '1' is 49 and so on. but since we are referring the matrix index, we are interested in 0,1,..
//So, the '0' should be subtracted . i.e. the 49 value of '1' will be 49-48=1.
int tid = omp_get_thread_num();
row[tid] = 2 * int(x[tid * 6] - '0') + int(x[tid * 6 + 5] - '0');
col[tid] = 8 * int(x[tid * 6 + 1] - '0') + 4 * int(x[tid * 6 + 2] - '0') + 2 * int(x[tid * 6 + 3] - '0') + int(x[tid * 6 + 4] - '0');
val[tid] = sbox[tid][row[tid]][col[tid]];
result[tid]= decimalToBinary(val[tid]);
}
Is there a way I can parallelize s-boxes to improve speedup? or is there another part of algorithm which can be parallelized to get maximum speedup? Any examples?
use auto range1= std::async(dowork) to calculate ranges in parallel and return range1.get()+range2.get() etc..
How many processes does this piece of code create?
for(int i = 0 ; i < 5 ; i++){
if(fork() == fork())
break;
}
The first parent spawns five children. Each of those spawns four children. Each of those spawns three children, and so on.
So it's:
5 * (1 + 4 * (1 + 3 * (1 + 2 * (1 + 1))))
Looks like 325 processes spawned, plus the original one.
Let's say I have 15 elements. I want to group them such a way that:
group1 = 1 - 5
group2 = 6 - 9
group3 = 10 - 12
group4 = 13 - 14
group5 = 15
This way I'll get elements in each group as below:
group1 = 5
group2 = 4
group3 = 3
group4 = 2
group5 = 1
As you can see loop interval is decreasing.
I took 15 just for an example. In actual programme it's user driven parameter which can be anything (hopefully few thousand).
Now what I'm looking for is:
Whatever is in group1 should have variable "loop" value 0, group2 should have 1, group3 should have 2 and so on... "loop" is an int variable which is being used to calculate some other stuff.
Let's put in other words too
I have an int variable called "loop". I want to assign value to it such a way that:
First n frames loop value 0 next (n -1) frames loop value 1 then next (n - 2) frames loop value 2 all the way to loop value (n - 1)
Let's say I have 15 frames on my timeline.
So n will be 5 ====>>>>> (5 + 4 + 3 + 2 + 1 = 15; as interval is decreasing by 1)
then
first 5 frames(1 - 5) loop is 0 then next 4 frames(6 - 9) loop is 1 then next 3 frames(10 - 12) loop is 2 then next 2 frames(13 - 14) loop is 3 and for last frame(15) loop is 4.
frames "loop" value
1 - 5 => 0
6 - 9 => 1
10 - 12 => 2
13 - 14 => 3
15 => 4
I've tried with modulo(%). But the issue is on frame 12 loop is 2 so (12 % (5 - 2)) remainder is 0 so it increments loop value.
The following lines are sample code which is running inside a solver. #loop is by default 0 and #Frame is current processing frame number.
int loopint = 5 - #loop;
if (#Frame % loopint == 0)
#loop += 1;
If I understand this correctly, then
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(int argc, char *argv[]) {
int n = atoi(argv[1]);
for(int i = 1; i <= n; ++i) {
printf("%d: %f\n", i, ceil((sqrt(8 * (n - i + 1) + 1) - 1) / 2));
}
}
is an implementation in C.
The math behind this is as follows: The 1 + 2 + 3 + 4 + 5 you have there is a Gauß sum, which has a closed form S = n * (n + 1) / 2 for n terms. Solving this for n, we get
n = (sqrt(8 * S + 1) - 1) / 2
Rounding this upward would give us the solution if you wanted the short stretches at the beginning, that is to say 1, 2, 2, 3, 3, 3, ...
Since you want the stretches to become progressively shorter, we have to invert the order, so S becomes (n - S + 1). Therefore the formula up there.
EDIT: Note that unless the number of elements in your data set fits the n * (n+1) / 2 pattern precisely, you will have shorter stretches either at the beginning or in the end. This implementation places the irregular stretch at the beginning. If you want them at the end,
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(int argc, char *argv[]) {
int n = atoi(argv[1]);
int n2 = (int) ceil((sqrt(8 * n + 1) - 1) / 2);
int upper = n2 * (n2 + 1) / 2;
for(int i = 1; i <= n; ++i) {
printf("%d: %f\n", i, n2 - ceil((sqrt(8 * (upper - i + 1) + 1) - 1) / 2));
}
}
does it. This calculates the next such number beyond your element count, then calculates the numbers you would have if you had that many elements.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
F is a function that number x has been repeated in an ascending order f(x).
x : 1 2 3 4 5 6 7 8 9 10
f(x): 1 2 2 3 3 3 4 4 4 4
my function gets 'x' and gives 'f(x)' and it has to do it without array but it goes wrong in high numbers.
int main()
{
int n;
cin>>n;
int i=1,a=1;
if(n==1)
cout<<'1';
else{
while(true){
a++;
i=i+a;
if(i>=n)
break;
}
}
cout<<a;
return 0;
}
TL;DR
f(x) = floor(0.5 + sqrt(1 + 8 * (x - 1)) / 2)
Explanation
Well, since this is a mathematical problem, just solve it with math ;)
One thing to notice is the correlation between the table and the triangular numbers:
h(x) = sum(range(1, x)) = x*(x + 1)/2 //triangular number
x 1 2 3 4 5 6 7 8 9 10
f(x) 1 2 2 3 3 3 4 4 4 4
h(f(x)) 1 3 3 6 6 6 10 10 10 10
So how does that help us? Well, we can write a new equation:
h(f(x)) = x | x = max({n | f(n) = f(x)})
And logically for the inverse the following should apply:
h^-1(x) = f(x)
No we've got two options:
Call it a day and just solve the rest via brute-force:
i = 1
sum = 0
while sum < x:
sum += i
i++
return i - 1
Or build our function h^-1(x):
h(x) = y = (x+1)x/2
h^-1(y) = x with h(x) = y
x ^ 2 + x - 2y = 0
solve for x using the quadratic formula:
x = 0.5 +/- sqrt(1 + 8y) / 2
Now this formula still lacks a few things:
we get two results, one of which is negative. We can just throw the negative result away, so +/- turns into +
this formula is 0-based. To be honest, I'm still trying to figure out why. Solution: simply decrement y by 1 to get the proper result
while this formula returns the correct result for the matching numbers, i.e. y = 3 -> x = 3, it returns floating-point numbers for other input, so we'll have to round down appropriately
Putting it together:
f(x) = floor(0.5 + sqrt(1 + 8 * (x - 1)) / 2)
int f(int x) {
return (x * (x + 1)) / 2;
}
int main() {
int n;
cin >> n;
int left = 1, right = n;
while(left < right) {
int mid = left + (right - left) / 2;
int val = f(mid);
if(val >= n) {
right = mid;
}
else {
left = mid + 1;
}
}
cout << left;
return 0;
}
Use binary search. Right now I am in mobile. I will add the explanation later if needed. Let me know if you don't understand anything.
This question already has answers here:
Is there a one-line function that generates a triangle wave?
(8 answers)
Closed 8 years ago.
in a for-loop with % to get a saw function, for example using a period of 5 printing 2 cycles would look like this:
for(auto i = 0; i < 5 * 2; ++i) cout << i % 5 << endl;
Results in:
0
1
2
3
4
0
1
2
3
4
I want a function returns a triangle wave, so for some function foo:
for(auto i = 0; i < 5 * 2; ++i) cout << foo(i, 5) << endl;
Would result in:
0
1
2
1
0
0
1
2
1
0
Is there such a function, or do I need to come up with my own?
Looks like a very similar question was answered here: Is there a one-line function that generates a triangle wave?
Taken from Noldorin answer:
Triangular Wave
y = abs((x++ % 6) - 3);
This gives a triangular wave of period 6, oscillating between 3 and 0.
Now put that in a function:
int foo(int inputPosition, int period, int amplitude)
{
return abs((inputPosition % period) - amplitude);
}
You'd have to make your own:
// Assumes 0 <= i < n
int foo(int i, int n) {
int ix = i % n;
if ( ix < n/2 )
return ix;
else
return n-1-ix;
}
I thought we should at least post the correct answer here before this question is closed cause it is a duplicate.
Eric Bainvile's answer is the correct one.
int foo(const int position, const int period){return period - abs(position % (2 * period) - period);}
However this gives a triangle wave with a range from [0, period] and a frequency of 2 * period and I want a range from [0, period / 2] and a cycle of period. This can be accomplished by just passing half of the period to foo or by adjusting the function:
int foo(const int position, const int period){return period / 2 - abs(position % period - period / 2);}
With such a simple function inlining seems preferable though so our final result will be:
for(auto position = 0; position < 5 * 2; ++position) cout << 5 / 2 - abs(position % 5 - 5 / 2) << endl;
Yielding the requested:
0
1
2
1
0
0
1
2
1
0