Skip to content

Instantly share code, notes, and snippets.

@Reznov9185
Created February 19, 2022 06:16
Show Gist options
  • Save Reznov9185/94a58fa24f4ee711020e3b77989f89fb to your computer and use it in GitHub Desktop.
Save Reznov9185/94a58fa24f4ee711020e3b77989f89fb to your computer and use it in GitHub Desktop.
Mthread_Proj1
#include <iostream>
#include <thread>
#include <string.h>
#include <random>
#include <stack>
#include <pthread.h>
#include <time.h>
using namespace std;
int T = 1; // No of threads (defaults to 1)
int N = 100; // Dimention N of the NxN 2D array (defaults to 100)
float V = 0.0; // Value of 2D array element (defaults to be assigned)
float **my_array; // 2D array pointer
int R, C; // Declare factors for num. of thread
float *sum; // Declare 1D sum array pointer
float *timing; // Declare 1D array pointer for thread timings
pthread_mutex_t lock;
pthread_t *thread_id;
int step = 0;
struct timespec start_time, end_time; // For thread timing
uint64_t diff; // For thread timing
uint64_t process_diff; // For n^2 timing
#define BILLION 1000000000L // For timing calc
int find_one_square_like_factor(int number)
{
stack<int> stack;
for (int i = 1; i <= number; ++i)
{
if (number % i == 0)
{
stack.push(i);
}
}
for (int i = 0; i < stack.size() / 2; i++)
{
stack.pop();
}
return stack.top();
}
float array_sum()
{
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start_time);
float sum = 0;
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
sum += my_array[i][j];
}
}
clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end_time);
process_diff = BILLION * (end_time.tv_sec - start_time.tv_sec) + end_time.tv_nsec - start_time.tv_nsec;
return sum;
}
void *thread_array_sum(void *arg)
{
pthread_mutex_lock(&lock);
clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start_time);
// Each thread computes sum of R, C of 2D array
int thread_part = step++;
for (int i = (thread_part * (N / R)); i < (thread_part + 1) * (N / R); i++)
{
// for(int j=0; j < N/C; j++){
// sum[thread_part] += my_array[i][j];
// }
for(int j=(thread_part * (N / C)); j < (thread_part + 1) * (N / C); j++){
sum[thread_part] += my_array[i][j];
}
}
clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end_time);
diff = BILLION * (end_time.tv_sec - start_time.tv_sec) + end_time.tv_nsec - start_time.tv_nsec;
timing[thread_part] = diff;
pthread_mutex_unlock(&lock);
return NULL;
}
int call_threads()
{
for (int i = 0; i < T; i++)
{
pthread_create(&thread_id[i], NULL, &thread_array_sum, &i);
}
return 0;
}
int main(int argc, char **argv)
{
for (int i = 0; i < argc; i++)
{
if (strcmp(argv[i], "-t") == 0 && i + 1 < argc && atoi(argv[i + 1]) > 0)
{
T = atoi(argv[i + 1]);
i++;
}
else if (strcmp(argv[i], "-s") == 0 && i + 1 < argc && atoi(argv[i + 1]) > 0)
{
N = atoi(argv[i + 1]);
i++;
}
else if (strcmp(argv[i], "-v") == 0 && i + 1 < argc && atoi(argv[i + 1]) > 0)
{
V = atof(argv[i + 1]);
i++;
}
}
// Declare 2D array with size NxN
my_array = new float *[N];
for (int i = 0; i < N; i++)
{
my_array[i] = new float[N];
}
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
if (V == 0.0)
{
my_array[i][j] = rand() / (RAND_MAX + 1.);
}
else
{
my_array[i][j] = V;
}
}
}
// Declare 1D sum array of size N
sum = new float[T];
// Declare 1D array for thread timings of size N
timing = new float[T];
// Init factors for num. of thread
R = find_one_square_like_factor(T);
C = T / R;
if (R < C)
{
swap(R, C);
}
// Init thread entity
thread_id = new pthread_t[T];
// Logs
cout << "T: " << T << "\n";
cout << "N: " << N << "\n";
cout << "V: " << V << "\n";
cout << "R: " << R << ", C: " << C << "\n";
cout << "Array sum: " << array_sum() << "\n";
call_threads();
for (int i = 0; i < T; i++)
{
pthread_join(thread_id[i], NULL);
}
pthread_mutex_destroy(&lock);
// Adding sum of all R,C parts
int total_sum = 0;
for (int i = 0; i < T; i++)
{
total_sum += sum[i];
}
cout << "Multithreaded Array Sum is: " << total_sum << endl;
// Timing for threads
for (int i = 0; i < T; i++)
{
cout << "Timing for thread["<< i << "]: (in nanosec.) " << timing[i] << "\n";
}
// Timing for n^2 process
cout << "Timing for the n^2 loop time: (in nanosec.) " << process_diff << "\n";
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment