diff --git a/ben b/ben new file mode 100755 index 0000000000000000000000000000000000000000..efe26d3b40c28a0340f979019bb6681c3cf47325 Binary files /dev/null and b/ben differ diff --git a/insertion_sort.c b/insertion_sort.c index 42d867717853c978fe58487e2e9ebe415a834f64..b8525327b5733227e35e0e6b0a977bceaa72d13e 100644 --- a/insertion_sort.c +++ b/insertion_sort.c @@ -1,38 +1,180 @@ /* Copyrights http://www.programmingsimplified.com/c/source-code/c-program-insertion-sort */ /* insertion sort ascending order */ - + #include <stdio.h> - +#include <assert.h> +#include <stdlib.h> +#include <time.h> +#include <mpi.h> + +int *create_rand_nums(int num_elements) +{ + int i; + int *rand_nums = (int *)malloc(sizeof(int) * num_elements); + assert(rand_nums != NULL); + for (i = 0; i < num_elements; i++) + + { + rand_nums[i] = rand() % num_elements; + } + return rand_nums; +} + int main() { - int n, array[1000], c, d, t; - - printf("Enter number of elements\n"); - scanf("%d", &n); - - printf("Enter %d integers\n", n); - - for (c = 0; c < n; c++) { - scanf("%d", &array[c]); - } - - for (c = 1 ; c <= n - 1; c++) { - d = c; - - while ( d > 0 && array[d] < array[d-1]) { - t = array[d]; - array[d] = array[d-1]; - array[d-1] = t; - - d--; - } - } - - printf("Sorted list in ascending order:\n"); - - for (c = 0; c <= n - 1; c++) { - printf("%d\n", array[c]); - } - - return 0; -} \ No newline at end of file + int i,j,k,num_elements,nameOfProcessor,numberOfProcessor,world_rank; + double startTime, finishTime; + + char processor_name[MPI_MAX_PROCESSOR_NAME]; + + MPI_Status stat; + MPI_Init(NULL,NULL); + + MPI_Comm_size(MPI_COMM_WORLD, &numberOfProcessor); + MPI_Comm_rank(MPI_COMM_WORLD, &world_rank); + MPI_Get_processor_name(processor_name, &nameOfProcessor); + unsigned int receivedElement; + if(world_rank == 0) { + + // create array and assign random number + scanf("%d", &num_elements); + unsigned int* bucket = malloc(sizeof(unsigned int)* num_elements); + bucket = create_rand_nums(num_elements); + + // starting time calculation + startTime = MPI_Wtime(); + + // looking for min and max value + unsigned int min = bucket[0]; + unsigned int max = bucket[0]; + for (i=1;i<num_elements;i++) { + if (bucket[i]>max) max = bucket[i]; + if (bucket[i]<min) min = bucket[i]; + } + + // calculating number of elements of each bucket + int *elementQtyArray = (int *)malloc(sizeof(int)* numberOfProcessor); + + // default values + for(i=1; i<numberOfProcessor; i++) { + elementQtyArray[i] = 0; + } + if (numberOfProcessor>1) { + for(i=0; i<num_elements; i++) { + int increaseOf = max/(numberOfProcessor-1); + int m = 1; + int range = 0; + for(j = increaseOf; j <= max; j = j + increaseOf) { + if(bucket[i] <= j) { + elementQtyArray[m]++; + range = 1; + break; + } + m++; + } + if (range==0) { + elementQtyArray[m-1]++; + } + } + + // Sending how many each process/bucket will get numbers + for(i=1; i<numberOfProcessor; i++) { + MPI_Send(&elementQtyArray[i], 1, MPI_INT, i, 0, MPI_COMM_WORLD); + } + + // doing the same, this time sending the numbers + for(i=0; i < num_elements; i++) { + int increaseOf = max/(numberOfProcessor-1); + int m = 1; + int range2 = 0; + for (j = increaseOf; j <= max; j = j + increaseOf) { + if(bucket[i] <= j) { + MPI_Send(&bucket[i], 1, MPI_UNSIGNED, m, 1, MPI_COMM_WORLD); + range2 = 1; + break; + } + m++; + } + if (range2==0) { + MPI_Send(&bucket[i], 1, MPI_UNSIGNED, m-1, 1, MPI_COMM_WORLD); + } + } + + // Getting back results and adding them to one array + int lastIndex = 0; int indexi = 0; + for(i=1; i < numberOfProcessor; i++) { + unsigned int * recvArray = (unsigned int *) malloc (sizeof(unsigned int) * elementQtyArray[i]); + MPI_Recv(&recvArray[0], elementQtyArray[i], MPI_UNSIGNED, i, 2, MPI_COMM_WORLD, &stat); + if(lastIndex == 0) { + lastIndex = elementQtyArray[i]; + } + for(j=0; j<elementQtyArray[i]; j++) { + bucket[indexi] = recvArray[j]; + indexi++; + } + } + } else { + int k; + for (i = 1 ; i <= num_elements - 1; i++) + { + j = i; + + while ( j > 0 && bucket[j] < bucket[j-1]) + { + k = bucket[j]; + bucket[j] = bucket[j-1]; + bucket[j-1] = k; + j--; + } + } + } + + + // stoping the time + finishTime = MPI_Wtime(); + + // sorting results + printf("it took %f seconds \n", finishTime-startTime); + printf("Numbers: %d \n", num_elements); + printf("Processes: %d \n", numberOfProcessor); + + } else { + + // if child process + int elementQtyUsed; + + // getting the number of elements from bucket + MPI_Recv(&elementQtyUsed, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &stat); + unsigned int *sub_array = malloc(sizeof(unsigned int) * elementQtyUsed); + + // getting elements from the main process + for(i = 0; i < elementQtyUsed; i++) { + MPI_Recv(&receivedElement, 1, MPI_UNSIGNED, 0, 1, MPI_COMM_WORLD, &stat); + sub_array[i] = receivedElement; + } + + // sorting bucket + for (i = 1 ; i <= elementQtyUsed - 1; i++) + { + j = i; + + while ( j > 0 && sub_array[j] < sub_array[j-1]) + { + k = sub_array[j]; + sub_array[j] = sub_array[j-1]; + sub_array[j-1] = k; + j--; + } + } + + // sending back sorted array + MPI_Send(sub_array, elementQtyUsed, MPI_UNSIGNED, 0, 2, MPI_COMM_WORLD); + } + + MPI_Finalize(); + + + return 0; + +} + diff --git a/mpi_hostfile b/mpi_hostfile new file mode 100644 index 0000000000000000000000000000000000000000..e66dad090e66c3d18e87e8ca121f63f314150aee --- /dev/null +++ b/mpi_hostfile @@ -0,0 +1,8 @@ +#daftar host +localhost +167.205.35.26 +167.205.35.28 +167.205.35.29 +167.205.35.30 +167.205.35.31 + diff --git a/perbandingan_waktu.txt b/perbandingan_waktu.txt new file mode 100644 index 0000000000000000000000000000000000000000..298ae1a2f63394c386e6f7d6c6388afd187eaf88 --- /dev/null +++ b/perbandingan_waktu.txt @@ -0,0 +1,79 @@ +Processes = 1 +Elements = 50000 +Time = 8.255 s + +Processes = 1 +Elements = 100000 +Time = 26.446 s + +Processes = 1 +Elements = 200000 +Time = 107.288 s + +Processes = 1 +Elements = 400000 +Time = 276.225 s + +Processes = 4 +Elements = 50000 +Time = 6.612 s + +Processes = 4 +Elements = 100000 +Time = 16.261 s + +Processes = 4 +Elements = 200000 +Time = 25.097 s + +Processes = 4 +Elements = 400000 +Time = 105.922 s + +Processes = 8 +Elements = 50000 +Time = 2.381 s + +Processes = 8 +Elements = 100000 +Time = 3.576 s + +Processes = 8 +Elements = 200000 +Time = 4.165 s + +Processes = 8 +Elements = 400000 +Time = 16.221 s + +Processes = 16 +Elements = 50000 +Time = 0.719 s + +Processes = 16 +Elements = 100000 +Time = 1.098 s + +Processes = 16 +Elements = 200000 +Time = 1.581 s + +Processes = 16 +Elements = 400000 +Time = 5.079 s + +Processes = 32 +Elements = 50000 +Time = 0.226 s + +Processes = 32 +Elements = 100000 +Time = 0.633 s + +Processes = 32 +Elements = 200000 +Time = 1.352 s + +Processes = 32 +Elements = 400000 +Time = 1.301 s