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.
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..
int power(int baseNum, int powNum) {
int result = 1;
for(int i = 0; i < powNum; i++) {
result = result * baseNum
}
return result;
}
int main()
{
cout <<power(2 , 3);
return 0;
It's from this YouTube Video.
So what I don't understand is how he picks int result = 1; out of nowhere? Why not = 2?
Why int i = 0 , why not = 1 ?
In the video part "Let's break it down" he says the first Result is 1
But isn't it 0?
First loop is 0
Next loop is 1
3rd loop is 2
and then it exits because it's 3 < 3
right?
If someone can make a transcription of the loops will be great so I can see exactly what's going on.
And the last thing how we make these calculations result = result * baseNum with the loops so we can get to 8.
I just started learning C++.
So what I don't understand is how he picks int result = 1; out of nowhere? Why not = 2?
That is so it's not always 0 if he multiplies the result in the for loop. 0 * 2 --> 0
About the for loop itself:
Iteration: 1 * 2 --> 2 / i = 0
Iteration: 2 * 2 --> 4 / i = 1
Iteration: 4 * 2 --> 8 / i = 2
Iteration: i = 3 / is not smaller than 3 leaves the for-loop
At the end he leaves the function and returns the result which is now 8.
For the for-loop, getting the the power of 3 with a base of 2, gives back the same as if you would just multiple 2 * 2 * 2.
That is exactly what the for-loop does you go through and do the first multiplication 1 * 2, on the second iteration you calculate you multiply the result again 2 * 2, then you go through again and calculate the next iteration 4 * 2 which then gets you the desired result
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.)
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.
I got an exam two days from now and my professor gave us an old exam with the solutions however after going over this problem countless of times I can't figure out how in the world the answer is the answer.
int recursive (int n) {
if (n < 10) return n;
return 100 * recursive (n / 100) + 10 * (n % 10);
}
int main(){
cout << recursive (19683) << endl;
return 0;
}
The answer should print out 16030 but I have no idea of how it gets that. I do
100*196+10*3 = 19630
Then I do
100*1+10*3 = 130
which is completely wrong would appreciate it if someone knew how to get to that answer
The first call (recursive(19683)) returns:
100 * recursive(196) + 10*3
The second call (recursive(196)) returns:
100 * recursive(1) + 10*6
The third call (recursive(1)) returns 1 directly. Substituting back, one gets:
100 * (100 * 1 + 60) + 30 = 10000 + 6000 + 30 = 16030
Back in high school we were taught to be able to desk check our code. Desk checking is where you compute, by hand, the result of every step.
int recursive (int n) {
if (n < 10) return n;
return 100 * recursive (n / 100) + 10 * (n % 10);
}
Pass this 19683
recursive(19683)
19683 < 10 is false
return 100 * recursive(196) + 10 * (19683 % 10 -> 3)
recursive(196)
196 < 10 is false
return 100 * recursive(1) + 10 * (196 % 10 -> 6)
recursive(1)
1 < 10 is true, return 1
substitute recursive(1) = 1 into earlier equation...
return 100 * 1 * 60 -> 160
substitute recursive(196) = 160 into earlier equation...
return 100 * 160 + 10 * 3 -> 16030
recursive(19683) = 100 * recursive(196) + 10 * 3
recursive(196) = 100 * recursive(1) + 10 * 6
recursive(1) = 1
Now back-fill the answers
recursive(196) = 100 + 60
recursive(19683) = 100 * 160 + 30 = 16030
In order to understand what's happening, look at a a simpler example of recursion, such as reversing a string. There's a good explanation of how recursion works in the answers to this question: -
Reverse a string using recursion
Once that makes sense to you, you should find understanding the example question you pose much easier.