void parallel_mandelbrot(struct mandelbrot_thread *args, struct mandelbrot_param *parameters) { #if LOADBALANCE == 1 // Use a stack if(args -> id == 0) { initStack(); } pthread_barrier_wait(&thread_para_barrier); int i; int RowsPerThread = ROWS_PER_TASK; float threadsInv = (float)ROWS_PER_TASK / (float)mandelbrot_param.height; float irange = mandelbrot_param.upper_i - mandelbrot_param.lower_i; int tasksPerThread = (mandelbrot_param.height / ROWS_PER_TASK) / NB_THREADS; for(i = tasksPerThread * args -> id; i < tasksPerThread * (args -> id + 1); i ++) { struct mandelbrot_param tempParam = mandelbrot_param; tempParam.height = ROWS_PER_TASK; tempParam.lower_i = irange * threadsInv * (float)i + mandelbrot_param.lower_i; tempParam.upper_i = irange * threadsInv * (float)(i + 1) + mandelbrot_param.lower_i; pushStack(&tempParam, ROWS_PER_TASK * i); } #endif #if LOADBALANCE == 0 int RowsPerThread = parameters -> height / NB_THREADS; float range = (float)RowsPerThread / (float)parameters -> height; float threadsInv = 1.0f / (float)NB_THREADS; float irange = parameters -> upper_i - parameters -> lower_i; struct mandelbrot_param tempParam = *parameters; tempParam.height = parameters -> height / NB_THREADS; tempParam.lower_i = irange * threadsInv * (float)args -> id + parameters -> lower_i; tempParam.upper_i = irange * threadsInv * (float)(args -> id + 1) + parameters -> lower_i; compute_chunk(&tempParam, RowsPerThread * args -> id, 0); #endif #if LOADBALANCE == 1 while (1) { struct mandelbrot_param_offset* theParamOffset = popStack(); if(theParamOffset == NULL) break; compute_chunk(&(theParamOffset -> theParam), theParamOffset -> heightOffset, 0); } #endif }
/* * Each thread starts individually this function, where args->id give the thread's id from 0 to NB_THREADS */ void parallel_mandelbrot(struct mandelbrot_thread *args, struct mandelbrot_param *parameters) { #if LOADBALANCE == 0 // naive *parallel* implementation. Compiled only if LOADBALANCE = 0 parameters->begin_h = (parameters->height / NB_THREADS) * args->id; if (args->id == NB_THREADS - 1) { parameters->end_h = parameters->height; } else { parameters->end_h = (parameters->height / NB_THREADS) * (args->id + 1); } parameters->begin_w = 0; parameters->end_w = parameters->width; printf("H[%d], W[%d]\n", parameters->height, parameters->width); printf("Running load-balance 0 with threadid [%d], computing chunk x: [%d] -> [%d], y: [%d] -> [%d]\n", args->id, parameters->begin_w, parameters->end_w, parameters->begin_h, parameters->end_h); compute_chunk(parameters); #endif #if LOADBALANCE == 1 // Your load-balanced smarter solution. Compiled only if LOADBALANCE = 1 int x, y; while (get_my_pixel(parameters, &x, &y)){ parameters->begin_h = y; parameters->end_h = y + 1; parameters->begin_w = x; parameters->end_w = x + 1; compute_chunk(parameters); } #endif #if LOADBALANCE == 2 // A second *optional* load-balancing solution. Compiled only if LOADBALANCE = 2 int row; while (get_my_row(parameters, &row)) { parameters->begin_h = row; parameters->end_h = row + 1; parameters->begin_w = 0; parameters->end_w = parameters->width; compute_chunk(parameters); } #endif }
void ChunkModelFactory::worker() { while(1) { std::unique_lock<std::mutex> ulock(mutex); chunks_condition.wait(ulock, [&]{return !chunks.empty();}); auto it = chunks.begin(); auto position = *it; chunks.erase(it); auto itr = model_data.find(position); if(itr == model_data.end()) continue; auto data = itr->second; model_data.erase(itr); ulock.unlock(); auto result = compute_chunk(data, block_data); if(result->size > 0) { std::lock_guard<std::mutex> ulock(mutex); models.push_back(result); created++; processed++; } else { std::lock_guard<std::mutex> ulock(mutex); empty++; processed++; } } }
void compute_rows(struct mandelbrot_param *parameters, int start_row, int end_row) { parameters->begin_h = start_row; parameters->end_h = end_row; parameters->begin_w = 0; parameters->end_w = parameters->width; compute_chunk(parameters); }
void sequential_mandelbrot(struct mandelbrot_param *parameters) { // Define the region compute_chunk() has to compute // Entire height: from 0 to picture's height parameters->begin_h = 0; parameters->end_h = parameters->height; // Entire width: from 0 to picture's width parameters->begin_w = 0; parameters->end_w = parameters->width; // Go compute_chunk(parameters); }
void sequential_mandelbrot(struct mandelbrot_param *parameters) { compute_chunk(parameters, 0, 0); }