/** * Plain barrier. This will block until all participating processes reach * this point. Note that the participating processes must take care to have * their sync_*() calls in the same order to avoid likely deadlock. * @return 0 (always) */ int blts_sync_anon() { if(!init_done) return 0; sync_mutex_lock(); barrier_sync(0); sync_mutex_unlock(); return 0; }
void * jacobi(void *args){ ARGS_FOR_THREAD *args_for_me = (ARGS_FOR_THREAD *)args; //Reset global variables after red-black done = 0; diff = 0; num_iter = 0; float local_diff = 0; /* While not converged */ while(done != 1){ local_diff = 0; if(num_iter % 2 == 0){ /* Every even iteration move from my_grid to temp grid */ for(int i = args_for_me->thread_id + 1; i < args_for_me->my_grid->dimension-1; i+=NUM_THREADS){ /* Row */ for(int j = 1; j < args_for_me->my_grid->dimension-1; j++){ /* Col */ int pos = i * args_for_me->my_grid->dimension + j; args_for_me->temp->element[pos] = \ 0.20*(args_for_me->my_grid->element[pos] + \ args_for_me->my_grid->element[(i - 1) * args_for_me->my_grid->dimension + j] +\ args_for_me->my_grid->element[(i + 1) * args_for_me->my_grid->dimension + j] +\ args_for_me->my_grid->element[i * args_for_me->my_grid->dimension + (j + 1)] +\ args_for_me->my_grid->element[i * args_for_me->my_grid->dimension + (j - 1)]); local_diff += fabs(args_for_me->my_grid->element[pos] - args_for_me->temp->element[pos]); /* Store difference in local variable */ } } } else{ /* Move from temp to my_grid */ for(int i = args_for_me->thread_id + 1; i < args_for_me->my_grid->dimension-1; i+=NUM_THREADS){ for(int j = 1; j < args_for_me->my_grid->dimension-1; j++){ int pos = i * args_for_me->my_grid->dimension + j; args_for_me->my_grid->element[pos] = \ 0.20*(args_for_me->temp->element[pos] + \ args_for_me->temp->element[(i - 1) * args_for_me->temp->dimension + j] +\ args_for_me->temp->element[(i + 1) * args_for_me->temp->dimension + j] +\ args_for_me->temp->element[i * args_for_me->temp->dimension + (j + 1)] +\ args_for_me->temp->element[i * args_for_me->temp->dimension + (j - 1)]); local_diff += fabs(args_for_me->my_grid->element[pos] - args_for_me->temp->element[pos]); } } } /* Lock to write to shared difference */ pthread_mutex_lock(&mutex); diff += local_diff; pthread_mutex_unlock(&mutex); if((float)diff/((float)(args_for_me->my_grid->dimension*args_for_me->my_grid->dimension)) < (float)TOLERANCE) done = 1; /* Barrier sync and reset difference */ barrier_sync(&barrier); } }
/* 各スレッドのナップザック処理 */ void t_knapsack(int num_thread,int tid,int *P,int *W,int N,int C){ int i,j,prg; --W;--P; for(i=1;i<=N;i++){ /* 列をスレッドで分ける */ int t = C / num_thread + 1; for(j=t*tid+1; j<=min(C,t*(tid+1)) ;j++){ int v = (j-W[i]>=0) ? P[i] + R[i-1][j-W[i]] : 0; R[i][j] = max(R[i-1][j],v); } /* 全てのスレッドが処理を完了するまで待機 */ barrier_sync(num_thread,tid); } }
/* The function executed by the threads. */ void * my_thread(void *args) { int thread_number = (int)args; int num_iterations; for(num_iterations = 0; num_iterations < NUM_ITERATIONS; num_iterations++){ printf("Thread number %d is processing for iteration %d. \n", thread_number, num_iterations); sleep(ceil((float)rand()/(float)RAND_MAX * 10)); /* simulate some processing. */ printf("Thread %d is at the barrier. \n", thread_number); barrier_sync(&barrier, thread_number); /* Wait here for all threads to catch up before starting the next iteration. */ } pthread_exit(NULL); }
/** * Block process until each registered user reaches named barrier. Note that * the participating processes must take care to have their sync_*() calls * in the same order to avoid likely deadlock. * @param tag Name of barrier, registered earlier with blts_sync_add_tag() * @return 0 on success */ int blts_sync_tagged(char *tag) { int i, ret = 0; if(!init_done) return 0; sync_mutex_lock(); i = find_tagged_barrier(tag); if(i < 0) { BLTS_ERROR("Sync: Named barrier '%s' not available\n", tag); ret = -EINVAL; } else { BLTS_TRACE("Sync: Arriving at named barrier '%s'\n", tag); barrier_sync(i); } sync_mutex_unlock(); return ret; }
void * red_black(void *args){ ARGS_FOR_THREAD *args_for_me = (ARGS_FOR_THREAD *)args; diff = 0; num_iter = 0; float local_diff; float temp; while(done != 1){ local_diff = 0; for(int i = args_for_me->thread_id + 1; i < args_for_me->my_grid->dimension-1; i+=NUM_THREADS){ if(is_red == 0){ /* Operate on only red points */ if(args_for_me->thread_id % 2 == 0){ /* Alternates positions starting with Red or Black */ for(int j = 1; j < args_for_me->my_grid->dimension-1; j+=2){ /* Advance by 2 points to jump over the black point */ int pos = i * args_for_me->my_grid->dimension + j; temp = args_for_me->my_grid->element[pos]; args_for_me->my_grid->element[pos] = \ 0.20*(args_for_me->my_grid->element[pos] + \ args_for_me->my_grid->element[(i - 1) * args_for_me->my_grid->dimension + j] +\ args_for_me->my_grid->element[(i + 1) * args_for_me->my_grid->dimension + j] +\ args_for_me->my_grid->element[i * args_for_me->my_grid->dimension + (j + 1)] +\ args_for_me->my_grid->element[i * args_for_me->my_grid->dimension + (j - 1)]); local_diff += fabs(args_for_me->my_grid->element[i * args_for_me->my_grid->dimension + j] - temp); } } else{ /* Starts one position in to start on Red */ for(int j = 2; j < args_for_me->my_grid->dimension-1; j+=2){ int pos = i * args_for_me->my_grid->dimension + j; temp = args_for_me->my_grid->element[pos]; args_for_me->my_grid->element[pos] = \ 0.20*(args_for_me->my_grid->element[pos] + \ args_for_me->my_grid->element[(i - 1) * args_for_me->my_grid->dimension + j] +\ args_for_me->my_grid->element[(i + 1) * args_for_me->my_grid->dimension + j] +\ args_for_me->my_grid->element[i * args_for_me->my_grid->dimension + (j + 1)] +\ args_for_me->my_grid->element[i * args_for_me->my_grid->dimension + (j - 1)]); local_diff += fabs(args_for_me->my_grid->element[i * args_for_me->my_grid->dimension + j] - temp); } } } else{ /* Operate on only black points */ if(args_for_me->thread_id % 2 == 0){ /* Starts one position in to start on black point */ for(int j = 2; j < args_for_me->my_grid->dimension-1; j+=2){ int pos = i * args_for_me->my_grid->dimension + j; temp = args_for_me->my_grid->element[pos]; args_for_me->my_grid->element[pos] = \ 0.20*(args_for_me->my_grid->element[pos] + \ args_for_me->my_grid->element[(i - 1) * args_for_me->my_grid->dimension + j] +\ args_for_me->my_grid->element[(i + 1) * args_for_me->my_grid->dimension + j] +\ args_for_me->my_grid->element[i * args_for_me->my_grid->dimension + (j + 1)] +\ args_for_me->my_grid->element[i * args_for_me->my_grid->dimension + (j - 1)]); local_diff += fabs(args_for_me->my_grid->element[i * args_for_me->my_grid->dimension + j] - temp); } } else{ for(int j = 1; j < args_for_me->my_grid->dimension; j+=2){ int pos = i * args_for_me->my_grid->dimension + j; temp = args_for_me->my_grid->element[pos]; args_for_me->my_grid->element[pos] = \ 0.20*(args_for_me->my_grid->element[pos] + \ args_for_me->my_grid->element[(i - 1) * args_for_me->my_grid->dimension + j] +\ args_for_me->my_grid->element[(i + 1) * args_for_me->my_grid->dimension + j] +\ args_for_me->my_grid->element[i * args_for_me->my_grid->dimension + (j + 1)] +\ args_for_me->my_grid->element[i * args_for_me->my_grid->dimension + (j - 1)]); local_diff += fabs(args_for_me->my_grid->element[i * args_for_me->my_grid->dimension + j] - temp); } } } } /* Lock and store shared difference */ pthread_mutex_lock(&mutex); diff += local_diff; pthread_mutex_unlock(&mutex); if((float)diff/((float)(args_for_me->my_grid->dimension*args_for_me->my_grid->dimension)) < (float)TOLERANCE) done = 1; /* Barrier sync, reset difference and alternate red/black */ barrier_sync(&barrier); } }