#include <iostream>
#include "pthread.h"
#include "vector"
#include "fstream"
#include "cstring"
#include "climits"
#include "chrono"
#include "ctime"
using namespace std;
using namespace std::chrono;
const long SIZE = 20000000; //the size of vector that need to be sorted
const int THREADS_NUM = 3; // the number of threads
long sortNumPerThread = SIZE / THREADS_NUM; // the number of vector that every thread needs to sort
string path = "/home/chunxiang/code/Cmaketest/src/vector.txt"; // file path of vector
vector<double> vec(SIZE), sortedVec(SIZE);
pthread_barrier_t barrier;
class Section{
public:
int left;
int right;
Section(){
};
};
void loadVector();
void quickSort(int left, int right);
void *pthread_sort(void *arg);
void merge();
void serial_quick_sort();
void loadVector() {
ifstream read_file(path);
string line;
for (int i = 0; i < SIZE; ++i) {
getline(read_file, line);
vec[i] = stod(line);
}
read_file.close();
}
void quickSort(int start, int end) {
if (start >= end)
return;
double base = vec[end];
int left = start, right = end - 1;
while (true) {
while (vec[left] < base)
++left;
while (vec[right] >= base)
--right;
if (left >= right)
break;
swap(vec[left], vec[right]);
}
if (vec[left] >= vec[end])
swap(vec[left], vec[end]);
else
++left;
quickSort(start, left - 1);
quickSort(left + 1, end);
}
void merge() {
vector<int> index(THREADS_NUM), index_most(THREADS_NUM);
for (int i = 0; i < THREADS_NUM; ++i) {
index[i] = i * sortNumPerThread;
if (i == THREADS_NUM - 1) {
index_most[i] = SIZE;
} else {
index_most[i] = (i + 1) * sortNumPerThread;
}
}
for (int i = 0; i < SIZE; ++i) {
int min_index;
double min_num = INT_MAX;
for (int j = 0; j < THREADS_NUM; ++j) {
if ((index[j] < (j + 1) * sortNumPerThread) && (vec[index[j]] < min_num)) {
min_num = vec[index[j]];
min_index = j;
}
}
sortedVec[i] = vec[index[min_index]];
index[min_index]++;
}
}
void serial_quick_sort() {
loadVector();
auto start = system_clock::now();
quickSort(0, SIZE - 1);
auto end = system_clock::now();
auto duration = duration_cast<microseconds>(end - start);
cout << "serial quick sort takes "
<< double(duration.count()) * microseconds::period::num / microseconds::period::den << " seconds" << endl;
}
void *pthread_sort(void *arg) {
Section* section = (Section*)arg;
quickSort(section->left, section->right);
//wait other threads
pthread_barrier_wait(&barrier);
}
int main() {
//serial_quick_sort();
loadVector();
pthread_t tid;
pthread_barrier_init(&barrier, NULL, THREADS_NUM + 1);
auto start = system_clock::now();
for (int i = 0; i < THREADS_NUM; ++i) {
Section* section = new Section;
section->left = i * sortNumPerThread;
if (i == THREADS_NUM - 1) {
section->right = SIZE - 1;
} else {
section->right = (i + 1) * sortNumPerThread - 1;
}
int status = pthread_create(&tid, NULL, pthread_sort, (void *) (section));
if (status != 0) {
cout << "create thread error" << endl;
return -1;
}
}
//main thread wait
pthread_barrier_wait(&barrier);
//merge results of per thread
merge();
auto end = system_clock::now();
auto duration = duration_cast<microseconds>(end - start);
cout << THREADS_NUM << " threads pthread-parallel quick sort takes "
<< double(duration.count()) * microseconds::period::num / microseconds::period::den << " seconds" << endl;
return 0;
}
//initector.cpp
#include "iostream"
#include "fstream"
#include "random"
#include "vector"
#include "string"
#include "sstream"
#include "cstdlib"
using namespace std;
const int vectorsize = 20000000;
string path = "/home/chunxiang/code/Cmaketest/src/vector.txt";
void writeAndInitVector(int size) {
vector<double> res(size, 0.0);
default_random_engine engine;
uniform_real_distribution<double> u(0.0, 20000);
for (int i = 0; i < size; ++i) {
res[i] = u(engine);
}
ofstream outfile(path);
for (int i = 0; i < size; ++i) {
outfile << res[i] << endl;
}
outfile.close();
}
void loadVector(int size) {
vector<double> res(size, 0);
ifstream file(path);
string line;
for (int i = 0; i < size; ++i) {
getline(file, line);
res[i] = stod(line);
}
file.close();
}
int main() {
writeAndInitVector(vectorsize);
//loadVector(size);
return 0;
}