Files
cs5890_high_performance_com…/HW2_PThreads/main.cpp
2020-11-08 10:50:29 -07:00

92 lines
2.9 KiB
C++

#include <iostream>
#include <pthread.h>
#include <cstdlib>
int thread_count, bin_count, data_count, thread_data_count, leftover_data_count;
float min_meas, max_meas, bin_size;
//setup global histogram with calloc.
int* global_histogram;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
void ParseArgs(int argc, char **args);
float* GenerateArray();
void * Work(void *pVoid);
int main(int argc, char* argv[]) {
///serial functions
ParseArgs(argc, argv);
float *array = static_cast<float *>(calloc(data_count, sizeof(*array)));
array = GenerateArray();
global_histogram = static_cast<int*>(calloc(bin_count, sizeof(*global_histogram)));
pthread_t thread[thread_count];
for(int i = 0; i < thread_count; i++){
//create all the threads
pthread_create(&thread[i], nullptr, Work, &array[i*(data_count/thread_count)]);
}
for(auto i = 0; i<thread_count; i++){
//wait for all the threads to finish.
pthread_join(thread[i], nullptr);
}
//cleanup leftovers
auto left_over_count = data_count % thread_count;
pthread_create(&thread[0], nullptr, Work, &array[data_count-left_over_count]);
pthread_join(thread[0], nullptr);
printf("bin range: ");
for (int i = 0; i < bin_count; i++){
float lo_bin = (float)i * bin_size + min_meas;
printf("[%f, %f) ", lo_bin, lo_bin+bin_size);
}
printf("\nbin count: ");
for (int i = 0; i < bin_count; i++) {
printf("bin %i [%i], ", i, global_histogram[i]);
}
pthread_exit(nullptr);
}
///Does the work to calculate the threads histogram
void * Work(void *pVoid){
auto *thread = (float*)pVoid;
for (int i = 0; i < data_count/thread_count ; i++){
int binNum = (int)((thread[i] - min_meas) / bin_size);
pthread_mutex_lock(&mutex);
global_histogram[binNum]++;
pthread_mutex_unlock(&mutex);
}
pthread_exit(NULL);
}
///Generates array of random.
float* GenerateArray(){
srand(100);
auto* returnArray = new float [data_count];
for(int i = 0; i < data_count; ++i)
returnArray[i] = (float) rand() / RAND_MAX * (max_meas - min_meas) + min_meas;
return returnArray;
}
void ParseArgs(int argc, char **args) {
//try and parse the args if anything is wrong throw an handle the exception.
try {
thread_count = std::stoi(args[1]);
bin_count = std::stoi(args[2]);
min_meas = std::stof(args[3]);
max_meas = std::stof(args[4]);
data_count = std::stoi(args[5]);
if(argc > 6)
throw;
bin_size = (max_meas-min_meas)/(float)bin_count;
// set the total data for each thread and account for the "extra"
thread_data_count = data_count/thread_count;
leftover_data_count = data_count % thread_count;
} catch (std::exception& e) {
std::cerr << "Invalid input data: " << std::endl << "\t"<<e.what() << std::endl;
}
}