Skip to content
Snippets Groups Projects
Commit 1f9441e8 authored by Dinda Yora Islami's avatar Dinda Yora Islami
Browse files

radixsort paralel

parent 113c2a1c
No related merge requests found
// C++ implementation of Radix Sort
#include <iostream>
#include <cstdlib>
#include <time.h>
using namespace std;
// A utility function to get maximum value in arr[]
int getMax(int arr[], int n)
{
int mx = arr[0];
for (int i = 1; i < n; i++)
if (arr[i] > mx)
mx = arr[i];
return mx;
}
// A function to do counting sort of arr[] according to
// the digit represented by exp.
__global__ void countSort(int arr[], int n, int exp)
{
int *output= (int*)malloc(sizeof(int)*n); // output array
int i, count[10] = {0};
// Store count of occurrences in count[]
for (i = 0; i < n; i++)
count[ (arr[i]/exp)%10 ]++;
// Change count[i] so that count[i] now contains actual
// position of this digit in output[]
for (i = 1; i < 10; i++)
count[i] += count[i - 1];
// Build the output array
for (i = n - 1; i >= 0; i--)
{
output[count[ (arr[i]/exp)%10 ] - 1] = arr[i];
count[ (arr[i]/exp)%10 ]--;
}
// Copy the output array to arr[], so that arr[] now
// contains sorted numbers according to current digit
for (i = 0; i < n; i++)
arr[i] = output[i];
}
// The main function to that sorts arr[] of size n using
// Radix Sort
void radixsort(int arr[], int n)
{
int *d_arr;
// Find the maximum number to know number of digits
int m = getMax(arr, n);
// Do counting sort for every digit. Note that instead
// of passing digit number, exp is passed. exp is 10^i
// where i is current digit number
cudaMalloc((void**)&d_arr,sizeof(int)*n);
cudaMemcpy(d_arr, arr, sizeof(int)*n,cudaMemcpyHostToDevice);
for (int exp = 1; m/exp > 0; exp *= 10) {
countSort<<<1,32>>>(arr, n, exp);
cudaMemcpy(arr, d_arr, sizeof(int)*n, cudaMemcpyDeviceToHost);
}
cudaFree(d_arr);
}
// A utility function to print an array
void print(int arr[], int n)
{
for (int i = 0; i < n; i++)
cout << arr[i] << "\n";
}
void rng(int* arr,int n){
int seed = 13516067;
srand(seed);
for (long i=0; i<n; i++){
arr[i] = (int) rand();
}
}
timespec diff(timespec start, timespec end)
{
timespec temp;
if ((end.tv_nsec - start.tv_nsec) < 0) {
temp.tv_sec = end.tv_sec - start.tv_sec - 1;
temp.tv_nsec = 1000000000 + end.tv_nsec - start.tv_nsec;
} else {
temp.tv_sec = end.tv_sec - start.tv_sec;
temp.tv_nsec = end.tv_nsec - start.tv_nsec;
}
return temp;
}
// Driver program to test above functions
int main()
{
timespec start, stop;
int n;
cout<<"Masukkan nilai N\n";
cin>>n;
int arr[n];
rng(arr,n);
clock_gettime(CLOCK_REALTIME, &start);
radixsort(arr,n);
clock_gettime(CLOCK_REALTIME, &stop);
print(arr,n);
timespec duration = diff(start, stop);
long time = duration.tv_sec * 1000000 + duration.tv_nsec/1000;
printf("\n%d.%09d s\n", duration.tv_sec, duration.tv_nsec);
return 0;
}
\ No newline at end of file
// C++ implementation of Radix Sort
#include <iostream>
#include <cstdlib>
#include <time.h>
#include <cuda.h>
#include <cuda_runtime.h>
#define MAX_THREAD 32
using namespace std;
// A utility function to get maximum value in arr[]
int getMax(int arr[], int n)
{
int mx = arr[0];
for (int i = 1; i < n; i++)
if (arr[i] > mx)
mx = arr[i];
return mx;
}
__global__ void storeCount(int *count, int *arr, int n, int exp){
__shared__ s_Count[MAX_THREAD][10]={0};
int idx = threadIdx.x;
if(n<=MAX_THREAD){
s_Count[idx][(arr[idx]/exp)%10 ]++;
} else{
int block = (int) ceil(n/MAX_THREAD);
int index = idx * block;
int last_index;
if(idx+1==MAX_THREAD){
last_index = n;
} else{
last_index= index + block;
}
for (int i = index; i < last_index; i++){
s_Count[idx][(arr[i]/exp)%10 ]++;
}
}
if(idx==0){
for (i = 1; i<MAX_THREAD;j++){
for(int j=0; j<10;j++){
s_Count[0][j]+=sCount[i][j];
}
}
for (j =0; j<10;j++){
count[j]=s_Count[0][j];
}
}
}
// A function to do counting sort of arr[] according to
// the digit represented by exp.
void countSort(int arr[], int n, int exp)
{
int *d_arr;
int *output= (int*)malloc(sizeof(int)*n); // output array
int i;
int d_count[10] = {0};
int h_count[10];
cudaMalloc((void**)&d_arr,sizeof(int)*n);
cudaMemcpy(d_arr, arr, sizeof(int)*n,cudaMemcpyHostToDevice);
// Store count of occurrences in count[]
storeCount<<<1,32>>>(d_count,d_arr,n,exp);
cudaMemcpy(h_count, d_count, 10,cudaMemcpyDeviceToHost);
// Change count[i] so that count[i] now contains actual
// position of this digit in output[]
for (i = 1; i < 10; i++)
h_count[i] += h_count[i - 1];
// Build the output array
for (i = n - 1; i >= 0; i--)
{
output[h_count[ (arr[i]/exp)%10 ] - 1] = arr[i];
h_count[ (arr[i]/exp)%10 ]--;
}
// Copy the output array to arr[], so that arr[] now
// contains sorted numbers according to current digit
for (i = 0; i < n; i++)
arr[i] = output[i];
cudaFree(d_arr);
//cudaFree(d_count);
}
// The main function to that sorts arr[] of size n using
// Radix Sort
void radixsort(int *arr, int n)
{
int m = getMax(arr, n);
// Do counting sort for every digit. Note that instead
// of passing digit number, exp is passed. exp is 10^i
// where i is current digit number
//cudaMemcpy(d_arr, arr, sizeof(int)*n,cudaMemcpyHostToDevice);
for (int exp = 1; m/exp > 0; exp *= 10)
countSort(arr,n,exp);
}
// A utility function to print an array
void print(int arr[], int n){
for (int i = 0; i < n; i++)
cout << arr[i] << "\n";
}
void rng(int* arr,int n){
int seed = 13516067;
srand(seed);
for (long i=0; i<n; i++){
arr[i] = (int) rand();
}
}
timespec diff(timespec start, timespec end)
{
timespec temp;
if ((end.tv_nsec - start.tv_nsec) < 0) {
temp.tv_sec = end.tv_sec - start.tv_sec - 1;
temp.tv_nsec = 1000000000 + end.tv_nsec - start.tv_nsec;
} else {
temp.tv_sec = end.tv_sec - start.tv_sec;
temp.tv_nsec = end.tv_nsec - start.tv_nsec;
}
return temp;
}
// Driver program to test above functions
int main(int argc, char *argv[])
{
timespec start, stop;
int n;
n= atoi(argv[1]);
int arr[n];
rng(arr,n);
clock_gettime(CLOCK_REALTIME, &start);
radixsort(arr,n);
clock_gettime(CLOCK_REALTIME, &stop);
print(arr,n);
timespec duration = diff(start, stop);
long time = duration.tv_sec * 1000000 + duration.tv_nsec/1000;
printf("\n%d.%09d s\n", duration.tv_sec, duration.tv_nsec);
//deallocate host memory
return 0;
}
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment