1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
|
// Benchmark for integer sorting speed across parallel threads.
//
// Copyright Steven Ross 2014
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/sort for library home page.
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/uniform_int_distribution.hpp>
#include <boost/sort/spreadsort/spreadsort.hpp>
#include <boost/thread.hpp>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <vector>
#include <iostream>
#include <fstream>
#include <string>
using std::string;
using namespace boost::sort::spreadsort;
#define DATA_TYPE string
static bool is_sorted(const std::vector<DATA_TYPE> &array) {
for (unsigned u = 0; u + 1 < array.size(); ++u) {
if (array[u] > array[u + 1]) {
return false;
}
}
return true;
}
static void sort_core(std::vector<DATA_TYPE> &array, bool stdSort,
unsigned loopCount) {
if (stdSort)
std::sort(array.begin(), array.end());
else
boost::sort::spreadsort::spreadsort(array.begin(), array.end());
if (!is_sorted(array)) {
fprintf(stderr, "sort failed!\n");
exit(1);
}
}
static void sort_loop(const std::vector<DATA_TYPE> &base_array, bool stdSort,
unsigned loopCount) {
std::vector<DATA_TYPE> array(base_array);
for (unsigned u = 0; u < loopCount; ++u) {
for (unsigned v = 0; v < base_array.size(); ++v) {
array[v] = base_array[v];
}
sort_core(array, stdSort, loopCount);
}
}
//Pass in an argument to test std::sort
int main(int argc, const char ** argv) {
std::ifstream indata;
std::ofstream outfile;
bool stdSort = false;
int constant_to_random_ratio = -1;
int threadCount = -1;
unsigned loopCount = 0;
for (int u = 1; u < argc; ++u) {
if (std::string(argv[u]) == "-std")
stdSort = true;
else if(threadCount < 0)
threadCount = atoi(argv[u]);
else if (!loopCount)
loopCount = atoi(argv[u]);
else
constant_to_random_ratio = atoi(argv[u]);
}
if (!loopCount) {
loopCount = 1;
}
printf("threads: %d loops: %d\n", threadCount, loopCount);
std::vector<DATA_TYPE> base_array;
if (constant_to_random_ratio >= 0) {
//Test for random data with gaps of identical data.
random::mt19937 generator;
random::uniform_int_distribution<int> distribution(0,255);
const int constant_to_random_count = 1000000;
const int string_length = 1000;
for (int i = 0; i < constant_to_random_count; ++i) {
DATA_TYPE temp(string_length, 'x'); // fill with default character.
for (int j = constant_to_random_ratio; j < string_length;) {
int val = distribution(generator);
temp[j] = val;
j += (val * constant_to_random_ratio)/128 + 1;
}
base_array.push_back(temp);
}
} else {
indata.open("input.txt", std::ios_base::in | std::ios_base::binary);
if (indata.bad()) {
printf("input.txt could not be opened\n");
return 1;
}
DATA_TYPE inval;
while (!indata.eof() ) {
indata >> inval;
base_array.push_back(inval);
}
}
// Sort the input
clock_t start, end;
double elapsed;
std::vector<boost::thread *> workers;
start = clock();
if (threadCount == 0) {
if (loopCount > 1) {
sort_loop(base_array, stdSort, loopCount);
} else {
sort_core(base_array, stdSort, loopCount);
}
threadCount = 1;
} else {
for (int i = 0; i < threadCount; ++i) {
workers.push_back(new boost::thread(sort_loop, base_array, stdSort,
loopCount));
}
for (int i = 0; i < threadCount; ++i) {
workers[i]->join();
delete workers[i];
}
}
end = clock();
elapsed = static_cast<double>(end - start) ;
printf("for %lu strings\n", base_array.size());
if (stdSort)
printf("std::sort clock time %lf\n", elapsed/CLOCKS_PER_SEC/threadCount);
else
printf("spreadsort clock time %lf\n", elapsed/CLOCKS_PER_SEC/threadCount);
return 0;
}
|