I am trying to modify a concurrency control algorithm to take advantage of priority of threads (i.e if lower priority thread and higher priority thread wants to enter critical section at same time, the higher priority thread goes in first, while the lower priority thread waits for certain no. of cycles).
Here is the modified algorithm:
procphase[i] = want_cr;
int j = turn;
do {
while (j != i) {
if (procphase[j] != out_cr)
{
if (procphase[j] == want_cr && thrd_prty[i]<thrd_prty[j])
{
if(turndown[i]<5)
{
turndown[i]=turndown[i]+1;
j=turn;
}
}
else if(procphase[j] ==claim_cr)
{
j=turn;
}
else{}
}
else j=(j+1)%n;
}
procphase[i] = claim_cr;
j = (j + 1) % n;
while (procphase[j] != claim_cr) j = (j + 1) % n;
} while (!(j == i && (turn == i || procphase[turn] == out_cr)));
turn = i;
The original algorithm is the Eisenberg McGuire algorithm,
but sometimes the algorithm is getting stuck in between and I could not find why.
Related
I have been trying to solve this problem :
" You have to travel to different villages to make some profit.
In each village, you gain some profit. But the catch is, from a particular village i, you can only move to a village j if and only if and the profit gain from village j is a multiple of the profit gain from village i.
You have to tell the maximum profit you can gain while traveling."
Here is the link to the full problem:
https://www.hackerearth.com/practice/algorithms/dynamic-programming/introduction-to-dynamic-programming-1/practice-problems/algorithm/avatar-and-his-quest-d939b13f/description/
I have been trying to solve this problem for quite a few hours. I know this is a variant of the longest increasing subsequence but the first thought that came to my mind was to solve it through recursion and then memoize it. Here is a part of the code to my approach. Please help me identify the mistake.
static int[] dp;
static int index;
static int solve(int[] p) {
int n = p.length;
int max = 0;
for(int i = 0;i<n; i++)
{
dp = new int[i+1];
Arrays.fill(dp,-1);
index = i;
max = Math.max(max,profit(p,i));
}
return max;
}
static int profit(int[] p, int n)
{
if(dp[n] == -1)
{
if(n == 0)
{
if(p[index] % p[n] == 0)
dp[n] = p[n];
else
dp[n] = 0;
}
else
{
int v1 = profit(p,n-1);
int v2 = 0;
if(p[index] % p[n] == 0)
v2 = p[n] + profit(p,n-1);
dp[n] = Math.max(v1,v2);
}
}
return dp[n];
}
I have used extra array to get the solution, my code is written in Java.
public static int getmaxprofit(int[] p, int n){
// p is the array that contains all the village profits
// n is the number of villages
// used one extra array msis, that would be just a copy of p initially
int i,j,max=0;
int msis[] = new int[n];
for(i=0;i<n;i++){
msis[i]=p[i];
}
// while iteraring through p, I will check in backward and find all the villages that can be added based on criteria such previous element must be smaller and current element is multiple of previous.
for(i=1;i<n;i++){
for(j=0;j<i;j++){
if(p[i]>p[j] && p[i]%p[j]==0 && msis[i] < msis[j]+p[i]){
msis[i] = msis[j]+p[i];
}
}
}
for(i=0;i<n;i++){
if(max < msis[i]){
max = msis[i];
}
}
return max;
}
I've got a serial version of BML and I'm trying to write a parallel one with OpenMP. Basically my code works with a main witin a loop calling two functions for horizontal and vertical moves. Like that:
for (s = 0; s < nmovss; s++) {
horizontal_movs(grid, N);
copy_sides(grid, N);
cur = 1-cur;
vertical_movs(grid, N);
copy_sides(grid, N);
cur = 1-cur;
}
Where cur is the current grid. Then horizontal and vertical functions are similar and have a nested loop:
for(i = 1; i <= n; i++) {
for(j = 1; j <= n+1; j++) {
if(grid[cur][i][j-1] == LR && grid[cur][i][j] == EMPTY) {
grid[1-cur][i][j-1] = EMPTY;
grid[1-cur][i][j] = LR;
}
else {
grid[1-cur][i][j] = grid[cur][i][j];
}
}
}
The code produces a ppm image at every step, and whit a certain input the serial version produce an output that we can suppose good. But using #pragma omp parallel for inside the two functions H and V, the ppm file results splitted in such zones as the number of threads(i.e. 4):
I suppose the problem is that every thread should be doing both functions in sequence before termitate because movememnts are strictcly connected. I don't know how to do that. If I set pragma at a highter level like before main loop, there is no speed-up. Obviously the ppm file has to be not sliced like the image.
Goin'on I tried this solution that gives me an identical result as the serial code, but I don't excatly understand why
# pragma omp parallel num_threads(thread_count) default(none) \
shared(grid, n, cur) private(i, j)
for(i = 1; i <= n+1; i++) {
# pragma omp for
for(j = 1; j <= n; j++) {
if(grid[cur][i-1][j] == TB && grid[cur][i][j] == EMPTY) {
grid[1-cur][i-1][j] = EMPTY;
grid[1-cur][i][j] = TB;
}
else {
grid[1-cur][i][j] = grid[cur][i][j];
}
}
}
}
Therefore, if i use just one thread more than available cores(4), the execution time "explodes" instead of remain barely the same.
ı want to calculate determinant of matrix with thread but i have a error "term does not eveluate to a function taking 0 arguments" ı want to solve big matrix with thread and parsing matrix,what can ı do
int determinant(int f[1000][1000], int x)
{
int pr, c[1000], d = 0, b[1000][1000], j, p, q, t;
if (x == 2)
{
d = 0;
d = (f[1][1] * f[2][2]) - (f[1][2] * f[2][1]);
return(d);
}
else
{
for (j = 1; j <= x; j++)
{
int r = 1, s = 1;
for (p = 1; p <= x; p++)
{
for (q = 1; q <= x; q++)
{
if (p != 1 && q != j)
{
b[r][s] = f[p][q];
s++;
if (s > x - 1)
{
r++;
s = 1;
}
}
}
}
for (t = 1, pr = 1; t <= (1 + j); t++)
pr = (-1)*pr;
c[j] = pr*determinant(b, x - 1);
}
for (j = 1, d = 0; j <= x; j++)
{
d = d + (f[1][j] * c[j]);
}
return(d);
}
}
int main()
{
srand(time_t(NULL));
int i, j;
printf("\n\nEnter order of matrix : ");
scanf_s("%d", &m);
printf("\nEnter the elements of matrix\n");
for (i = 1; i <= m; i++)
{
for (j = 1; j <= m; j++)
{
a[i][j] = rand() % 10;
}
}
thread t(determinant(a, m));
t.join();
printf("\n Determinant of Matrix A is %d .", determinant(a, m));
}
The immediate problem is that here: thread t(determinant(a, m)); you pass the result of calling determinant(a, m) as the function to execute, and zero arguments to call that function with - but an int is not a function or other callable object, which is what the error you got complains about.
std::thread's constructor takes the function to run and the arguments to supply separately, so you would need to call std::thread(determinant, a, m).
Now we have another problem, std::thread doesn't provide a way to retrieve the return value, and so you calculate it again here: printf("\n Determinant of Matrix A is %d .", determinant(a, m));.
To fix this, we can use std::async from the <future> header, which will manage the thread handling for us, and lets us retrieve the result later:
auto result = std::async(std::launch::async, determinant, a, m);
int det = result.get()
This will run determinant(a,m) on a new thread, and return a std::future<int> into which the return value may eventually be placed.
We can then try to retrieve that value with std::future::get(), which will block until the value can be retrieved (or until an exception occurs in the thread).
In this example, we still execute determinant in a pretty serial fashion, since we delegate the work to a thread, then wait for that thread to finish its work before continuing.
However we are now free to store the future, and defer calling std::future::get() until we actually need the value, potentially much later in your program.
There are a few other problems in the rest of your code:
all your array indexing is off by one (array indices run from 0 to N-1 in C and C++)
a few of the variables you're using don't exist (like a and m)
C-arrays are passed by pointer, so if you ever change the code not to block on the thread right there, the array will go out of scope and your thread may read garbage from the dangling pointer. If you use a proper container like std::array or std::vector, you can pass it by value so your thread will own the data to operate on for its entire lifetime.
I'm having a hard time figuring out how to break out of a loop using OpenMPI in c.
Here's my loop
for( i=1; i<=steps;i++) {
do_calculation(psi,new_psi,&mydiff,i1,i2,j1,j2);
if (breakNow == 1) {
break;
}
diff = find_difference();
if(myid == mpi_master && i % iout == 0){
printf("%8d %15.5f\n",i,diff);
if (diff == 0.00) {
printf("DONE!");
breakNow = 1;
MPI_Bcast(&breakNow, 1, MPI_INT, mpi_master, MPI_COMM_WORLD);
}
}
}
I need to break all of the processors out of the loop when there is a difference of 0.00 but it seems like the breakNow variable isn't being broadcast to all the processors. Am I missing something?
MPI_Bcast is a collective operation. You need to call it in all processes in order for it to complete. In the process whose rank matches mpi_root the broadcast will behave like a send operation and in all other ranks it will behave as a receive operation.
Just move the call to MPI_Bcast outside of the conditional. May be the right place is just before the if (breakNow == 1) break; line.
Another suggestion: if find_difference returns the same value in all processes, you can do something similar to:
for (i = 1; i <= steps; i++) {
do_calculation(psi, new_psi, &mydiff, i1, i2, j1, j2);
diff = find_difference();
if (i % iout == 0) {
if (myid == mpi_master) {
printf("%8d %15.5f\n", i, diff);
if (diff == 0.00)
printf("DONE!");
}
if (diff == 0.00) break;
}
}
If find_difference only gives meaningful results in the master process, then modify as follows:
for (i = 1; i <= steps; i++) {
do_calculation(psi, new_psi, &mydiff, i1, i2, j1, j2);
diff = find_difference();
if (i % iout == 0) {
if (myid == mpi_master) {
printf("%8d %15.5f\n", i, diff);
if (diff == 0.00)
printf("DONE!");
}
MPI_Bcast(&diff, 1, MPI_DOUBLE, mpi_master, MPI_COMM_WORLD);
if (diff == 0.00) break;
}
}
(I have assumed that diff is of type double and preserved the original semantics of your code to check for zero difference once every iout steps)
I'm writing a Conway's life game for school. In the program I am having trouble with the arrays taking the values I am assigning them. At one point in the program they print out the value assigned to them (1) yet at the end of the program when I need to print the array to show the iterations of the game it shows an incredibly low number. The other trouble was I was encountering difficulties when putting in a loop that would ask if it wants you to run another iteration. So I removed it until the previous errors were fixed.
Im writing this with C++
#include <stdio.h>
int main (void)
{
int currentarray [12][12];
int futurearray [12][12];
char c;
char check = 'y';
int neighbors = 0;
int x = 0; // row
int y = 0; //column
printf("Birth an organism will be born in each empty location that has exactly three neighbors.\n");
printf("Death an organism with four or more organisms as neighbors will die from overcrowding.\n");
printf("An organism with fewer than two neighbors will die from loneliness.\n");
printf("Survival an organism with two or three neighbors will survive to the next generation.\n");
printf( "To create life input x, y coordinates.\n");
while ( check == 'y' )
{
printf("Enter x coordinate.\n");
scanf("%d", &x ); while((c = getchar()) != '\n' && c != EOF);
printf("Enter y coordinate.\n");
scanf("%d", &y ); while((c = getchar()) != '\n' && c != EOF);
currentarray [x][y] = 1;
printf ("%d\n", currentarray[x][y]);
printf( "Do you wish to enter more input? y/n.\n");
scanf("%c", &check); while((c = getchar()) != '\n' && c != EOF);
}
// Note - Need to add a printf statement showing the array before changes are made after input added.
// check for neighbors
while(check == 'y')
{
for(y = 0; y <= 12; y++)
{
for(x = 0; x <= 12; x++)
{
//Begin counting number of neighbors:
if(currentarray[x-1][y-1] == 1) neighbors += 1;
if(currentarray[x-1][y] == 1) neighbors += 1;
if(currentarray[x-1][y+1] == 1) neighbors += 1;
if(currentarray[x][y-1] == 1) neighbors += 1;
if(currentarray[x][y+1] == 1) neighbors += 1;
if(currentarray[x+1][y-1] == 1) neighbors += 1;
if(currentarray[x+1][y] == 1) neighbors += 1;
if(currentarray[x+1][y+1] == 1) neighbors += 1;
//Apply rules to the cell:
if(currentarray[x][y] == 1 && neighbors < 2)
futurearray[x][y] = 0;
else if(currentarray[x][y] == 1 && neighbors > 3)
futurearray[x][y] = 0;
else if(currentarray[x][y] == 1 && (neighbors == 2 || neighbors == 3))
futurearray[x][y] = 1;
else if(currentarray[x][y] == 0 && neighbors == 3)
futurearray[x][y] = 1;
}
}
}
// Set the current array to the future and change the future to 0
{
for(y = 0; y < 12; y++)
{
for(x = 0; x < 12; x++)
{
//Begin the process
currentarray [x][y] = futurearray [x][y];
futurearray [x][y] = 0;
}
}
}
{
for(y = 0; y < 12; y++)
{
for(x = 0; x < 12; x++)
{
//print the current life board
printf("%d ", currentarray[x][y]);
}
}
}
// Have gone through one iteration of Life
//Ask to do another iteration
printf("Do you wish to continue y/n?\n");
scanf("%c", &check); while((c = getchar()) != '\n' && c != EOF);
return 0;
}
You are defining your arrays as [12][12].
In your generation loop you walk from i = 0 to i <= 12, which is 13 steps instead of the 12 of the array. Additionally you are trying to access x-1 and y-1, which can be as low as -1. Again not inside your array.
Sometimes you get semi-useful values from within your array, but on some borders you are just accessing random data.
Try to correct your border.
You forgot to set neighbors to 0 before counting them.
Since this is C++ (not C), you might as well declare neighbors inside the loop body. Makes these kinds of issues easier to spot, too.
Also, is it me, or is that while loop never going to finish? Your braces are a mess, in general, as is your indentation. You could do yourself and us a favour by cleaning those up.
Obviously agree with all the above suggestions. One nice trick you might want to implement with Life is to create an extra border around your area. So if the user wants a 12x12 grid (and you should allow width/height to be specified and allocate memory dynamically) internally you hold a 14x14 grid corresponding to a border around the actual grid. Before running the calculation copy the top row to the bottom border, bottom row to the top border etc. Now you can run the main algorithm on the inner 12x12 grid without worrying about edge cases. This will enable your patterns to re-appear on the other side if they fall off the edge.
You're also forgetting to set the values of both arrays to zero. This will take care of the ridiculous number issue you're having. you can do that by copying this for loop:
for(y = 0; y < 12; y++)
{
for(x = 0; x < 12; x++)
{
//Begin the process
currentarray [x][y] = futurearray [x][y];
futurearray [x][y] = 0;
}
}
and pasting it before the while loop but instead of setting currentarray[x][y] = futurearray[x][y], set it to 0. Also, if the coordinates are viewable locations instead of array co-ordinates, you'll want to change this:
printf ("%d\n", currentarray[x][y]);
to this:
printf ("%d\n", currentarray[x-1][y-1]);
I would also recommend putting a printf with a newline (\n) after each row has been printed and a tab (\t) after each item so that the formatting looks cleaner.