Finish Lab 3
This commit is contained in:
		
							
								
								
									
										17
									
								
								Lab3/examples/1-no_join-fixed.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								Lab3/examples/1-no_join-fixed.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,17 @@
 | 
				
			|||||||
 | 
					/**To compile, don't forget to add -lpthread. Might not work without that */
 | 
				
			||||||
 | 
					#include<pthread.h>
 | 
				
			||||||
 | 
					#include<stdio.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void* run (void* arg){
 | 
				
			||||||
 | 
					    printf("Hello from run\n");
 | 
				
			||||||
 | 
					    return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main(){
 | 
				
			||||||
 | 
					    pthread_t thread; // variable to store the reference to the thread
 | 
				
			||||||
 | 
					    pthread_create(&thread, NULL, &run, NULL);
 | 
				
			||||||
 | 
					    printf("In main"); // This section will be executed in parallel
 | 
				
			||||||
 | 
					    pthread_join(thread,NULL); // necessary for waiting for the thread to finish
 | 
				
			||||||
 | 
					    printf("In main 2");
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										23
									
								
								Lab3/examples/2-sleep no_join-fixed.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								Lab3/examples/2-sleep no_join-fixed.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,23 @@
 | 
				
			|||||||
 | 
					#include<pthread.h>
 | 
				
			||||||
 | 
					#include<stdio.h>
 | 
				
			||||||
 | 
					#include<stdlib.h>
 | 
				
			||||||
 | 
					#include<unistd.h>
 | 
				
			||||||
 | 
					#include<time.h>
 | 
				
			||||||
 | 
					#include<sys/time.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void* run (void* arg){
 | 
				
			||||||
 | 
					    printf("Hello from run\n");
 | 
				
			||||||
 | 
					    return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main(){
 | 
				
			||||||
 | 
					    pthread_t thread;
 | 
				
			||||||
 | 
					    pthread_create(&thread, NULL, &run, NULL);
 | 
				
			||||||
 | 
					    // While the sleep() function will appear to provide synchronization,
 | 
				
			||||||
 | 
					    // it is incorrect, and if used for this purposes instead of join
 | 
				
			||||||
 | 
					    // or synchronization mechanism - the grade for the assignment will be
 | 
				
			||||||
 | 
					    // reduced
 | 
				
			||||||
 | 
					    sleep(2);
 | 
				
			||||||
 | 
					    printf("Back in main");
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										24
									
								
								Lab3/examples/3-losing_track_of_threads-fixed.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								Lab3/examples/3-losing_track_of_threads-fixed.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
				
			|||||||
 | 
					#include<pthread.h>
 | 
				
			||||||
 | 
					#include<stdio.h>
 | 
				
			||||||
 | 
					#include<stdlib.h>
 | 
				
			||||||
 | 
					#include<unistd.h>
 | 
				
			||||||
 | 
					#include<time.h>
 | 
				
			||||||
 | 
					#include<sys/time.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void* run (void* arg){
 | 
				
			||||||
 | 
					    sleep(10-(int)arg);
 | 
				
			||||||
 | 
					    printf("Hello from run\n");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main(){
 | 
				
			||||||
 | 
					    pthread_t thread[10];
 | 
				
			||||||
 | 
					    int i = 0;
 | 
				
			||||||
 | 
					    for (i = 0 ; i < 10; ++i)
 | 
				
			||||||
 | 
					        pthread_create(&thread[i], NULL, &run,(void*)i);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // If you plan to use the results of all the threads, consider
 | 
				
			||||||
 | 
					    // using join for all of the threads
 | 
				
			||||||
 | 
					    for (i = 0 ; i < 10; ++i)
 | 
				
			||||||
 | 
					        pthread_join(thread[i],NULL);
 | 
				
			||||||
 | 
					    printf("In main");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										21
									
								
								Lab3/examples/4-passing_data_wrongly.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								Lab3/examples/4-passing_data_wrongly.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,21 @@
 | 
				
			|||||||
 | 
					#include<pthread.h>
 | 
				
			||||||
 | 
					#include<stdio.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void* run (void* arg){
 | 
				
			||||||
 | 
					    int i = (int) arg;
 | 
				
			||||||
 | 
					    printf("Hello from run, arg is %i\n",i);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main(){
 | 
				
			||||||
 | 
					    pthread_t thread[10];
 | 
				
			||||||
 | 
					    int i = 0;
 | 
				
			||||||
 | 
					    for (i = 0 ; i < 10; ++i)
 | 
				
			||||||
 | 
					        pthread_create(&thread, NULL, &run,(void*)i);
 | 
				
			||||||
 | 
					    // Notice how warnings are generated. This can be resolved by properly
 | 
				
			||||||
 | 
					    // allocating space for the thread parameters.
 | 
				
			||||||
 | 
					    // Note, that if you are using stack variable, the values might be corrupted
 | 
				
			||||||
 | 
					    for (i = 0 ; i < 10; i++){
 | 
				
			||||||
 | 
					        pthread_join(thread[i],NULL);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    printf("In main");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										31
									
								
								Lab3/examples/4-passing_data_wrongly_fixed.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								Lab3/examples/4-passing_data_wrongly_fixed.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,31 @@
 | 
				
			|||||||
 | 
					#include<pthread.h>
 | 
				
			||||||
 | 
					#include<stdio.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct thread_args{
 | 
				
			||||||
 | 
					    char letter;
 | 
				
			||||||
 | 
					    int id;
 | 
				
			||||||
 | 
					}Args;
 | 
				
			||||||
 | 
					void* run (void* arg){
 | 
				
			||||||
 | 
					    Args* argg = (Args*) arg;
 | 
				
			||||||
 | 
					    int i = argg->id;
 | 
				
			||||||
 | 
					    printf("Hello from run %d\n", i);
 | 
				
			||||||
 | 
					    return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main(int argc, char** argv){
 | 
				
			||||||
 | 
					    pthread_t thread[10];
 | 
				
			||||||
 | 
					    int i = 0;
 | 
				
			||||||
 | 
					    for (i = 0 ; i < 10; i++){
 | 
				
			||||||
 | 
					        Args* argg = (Args*) (malloc(sizeof(Args)));
 | 
				
			||||||
 | 
					        argg->letter = 'q';
 | 
				
			||||||
 | 
					        argg->id = i;
 | 
				
			||||||
 | 
					        pthread_create(&(thread[i]), NULL, &run,(void*)argg);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    for (i = 0 ; i < 10; i++){
 | 
				
			||||||
 | 
					        pthread_join(thread[i],NULL);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    // Free the resources somewhere, for long running program. Or let the OS handle that
 | 
				
			||||||
 | 
					    printf("In main");
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										19
									
								
								Lab3/examples/5-pthread_detach.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								Lab3/examples/5-pthread_detach.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
				
			|||||||
 | 
					#include<pthread.h>
 | 
				
			||||||
 | 
					#include<stdio.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void* run (void* arg){
 | 
				
			||||||
 | 
					    printf("Hello from run\n");
 | 
				
			||||||
 | 
					    return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main(){
 | 
				
			||||||
 | 
					    pthread_t thread;
 | 
				
			||||||
 | 
					    pthread_create(&thread, NULL, &run, NULL);
 | 
				
			||||||
 | 
					    pthread_detach(thread);
 | 
				
			||||||
 | 
					    // This command will make thread detached. This means the resources will be released 
 | 
				
			||||||
 | 
					    // upon the thread's completion - calling return
 | 
				
			||||||
 | 
					    // However, detached threads cannot be joined, which means if you care about the result
 | 
				
			||||||
 | 
					    // of the thread execution - you should not be using pthread_detach
 | 
				
			||||||
 | 
					    printf("In main");
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										71
									
								
								Lab3/main.c
									
									
									
									
									
								
							
							
						
						
									
										71
									
								
								Lab3/main.c
									
									
									
									
									
								
							@@ -1,8 +1,42 @@
 | 
				
			|||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Question 1: Run the program with the problem size of 1000 and 10 threads, what is the approximate speedup you are achieving?
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Answer 1: On my home machine single threading took 0.640239 seconds and multithreading took 0.194644 seconds.
 | 
				
			||||||
 | 
					 * On the lab machine single threading took 0.697472 seconds and multithreading took 0.114415 seconds.
 | 
				
			||||||
 | 
					 * This means that the my home machine is 3.29 times faster and the lab machine is 6.10 times faster.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Question 2: Is there a problem size / number of threads combination that slows down the computation process? Why do you think it is happening?
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Answer 2: There is a problem with having too many threads for the number of hardware threads available. Increasing past this only
 | 
				
			||||||
 | 
					 * increases the overhead of creating and managing the threads. This is because the threads are not running in parallel and are instead
 | 
				
			||||||
 | 
					 * being switched between by the OS. At lower matrix sizes the cost of creating threads and managing them is greater than the cost of
 | 
				
			||||||
 | 
					 * just doing the computation in a single thread, so any combination where threads > the number of hardware threads will be slower, and
 | 
				
			||||||
 | 
					 * as the matrix size approaches 1, than the greater effect thread creation and management will have on the speed of the program.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Question 3: What is the minimum size of the problem that benefits from creating an extra thread?
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Answer 3: The lowest size on my home machine that consistently benefited from an extra thread was 150, but this can change depending
 | 
				
			||||||
 | 
					 * on the specifications of the machine.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Question 4: Does using the threads always improve execution duration?
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Answer 4: No, as the number of threads increases past the number of hardware threads available the execution duration increases
 | 
				
			||||||
 | 
					 * due to managing the threads, as well as low size matrices where the cost of creating and managing threads is greater than the
 | 
				
			||||||
 | 
					 * cost of just doing the computation in a single thread.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Question 5: Guesstimate and comment on the nature of growth of the speedup with the number of threads – is it linear, exponential, are there any limits?
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Answer 5: The speedup is linear up to the number of hardware threads available, given a large enough matrix size.
 | 
				
			||||||
 | 
					 * Given a matrix of size x, the speedup of using y threads is approximately x/y, up to the number of hardware threads available.
 | 
				
			||||||
 | 
					 * After this the speedup will decrease as the number of threads increases, due to the overhead of creating and managing threads.
 | 
				
			||||||
 | 
					 **/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
#include <sys/time.h>
 | 
					#include <sys/time.h>
 | 
				
			||||||
 | 
					#include <time.h>
 | 
				
			||||||
#include <stdlib.h>
 | 
					#include <stdlib.h>
 | 
				
			||||||
#include<unistd.h>
 | 
					 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <pthread.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define MAXN 5
 | 
					#define MAXN 5
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -82,6 +116,23 @@ void *multiply_matrices_threaded(void *threadParams) {
 | 
				
			|||||||
     * threading capacity and parallelize the computation in such a
 | 
					     * threading capacity and parallelize the computation in such a
 | 
				
			||||||
     * way that a thread computes result per one or more rows
 | 
					     * way that a thread computes result per one or more rows
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
 | 
					    ThreadParams *t = (ThreadParams *) threadParams;
 | 
				
			||||||
 | 
					    int N = t->size;
 | 
				
			||||||
 | 
					    int row = t->row_index;
 | 
				
			||||||
 | 
					    int column = 0;
 | 
				
			||||||
 | 
					    int temp_result = 0;
 | 
				
			||||||
 | 
					    while (row < N) {
 | 
				
			||||||
 | 
					        column = 0;
 | 
				
			||||||
 | 
					        while (column < N) {
 | 
				
			||||||
 | 
					            temp_result = 0;
 | 
				
			||||||
 | 
					            for (int i = 0; i < t->size; i++) {
 | 
				
			||||||
 | 
					                temp_result = temp_result + t->first_array[row][i] * t->second_array[i][column];
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            t->result[row][column] = temp_result;
 | 
				
			||||||
 | 
					            column = column + 1;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        row += t->max_threads;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int main(int argc, char **argv) {
 | 
					int main(int argc, char **argv) {
 | 
				
			||||||
@@ -121,6 +172,22 @@ int main(int argc, char **argv) {
 | 
				
			|||||||
     * Write your code to create and use max_threads here, such that the threaded_result 
 | 
					     * Write your code to create and use max_threads here, such that the threaded_result 
 | 
				
			||||||
     * is populated with the result of the computation.
 | 
					     * is populated with the result of the computation.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
 | 
					    thr->result = threaded_result;
 | 
				
			||||||
 | 
					    pthread_t threads[max_threads];
 | 
				
			||||||
 | 
					    for (int i = 0; i < max_threads; i++) {
 | 
				
			||||||
 | 
					        ThreadParams *params = (ThreadParams *) malloc(sizeof(ThreadParams));
 | 
				
			||||||
 | 
					        params->first_array = array1;
 | 
				
			||||||
 | 
					        params->second_array = array2;
 | 
				
			||||||
 | 
					        params->result = threaded_result;
 | 
				
			||||||
 | 
					        params->row_index = i;
 | 
				
			||||||
 | 
					        params->size = size;
 | 
				
			||||||
 | 
					        params->max_threads = max_threads;
 | 
				
			||||||
 | 
					        pthread_create(&threads[i], NULL, &multiply_matrices_threaded, (void *) params);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    for (int i = 0; i < max_threads; i++) {
 | 
				
			||||||
 | 
					        pthread_join(threads[i], NULL);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    gettimeofday(&end, NULL);
 | 
					    gettimeofday(&end, NULL);
 | 
				
			||||||
    //The next line is inspired by https://linuxhint.com/gettimeofday_c_language/
 | 
					    //The next line is inspired by https://linuxhint.com/gettimeofday_c_language/
 | 
				
			||||||
    microseconds = (end.tv_sec * 1000000 + end.tv_usec) - (begin.tv_sec * 1000000 + begin.tv_usec);
 | 
					    microseconds = (end.tv_sec * 1000000 + end.tv_usec) - (begin.tv_sec * 1000000 + begin.tv_usec);
 | 
				
			||||||
@@ -129,7 +196,7 @@ int main(int argc, char **argv) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    if (check_if_matrices_differ(result, threaded_result, size) != 0) {
 | 
					    if (check_if_matrices_differ(result, threaded_result, size) != 0) {
 | 
				
			||||||
        printf("Threaded result differ from single core computation, error\n");
 | 
					        printf("Threaded result differ from single core computation, error\n");
 | 
				
			||||||
        exit(0);
 | 
					        exit(1);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
							
								
								
									
										9
									
								
								Lab3/try-for-error.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								Lab3/try-for-error.sh
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
				
			|||||||
 | 
					#!/bin/bash
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cond=0
 | 
				
			||||||
 | 
					while [ $cond -eq 0 ]
 | 
				
			||||||
 | 
					do
 | 
				
			||||||
 | 
					    ./build/Lab3 10 10 &> output.txt
 | 
				
			||||||
 | 
					    cond=$?
 | 
				
			||||||
 | 
					    echo $cond
 | 
				
			||||||
 | 
					done
 | 
				
			||||||
		Reference in New Issue
	
	Block a user