111 lines
3.2 KiB
C++
Raw Normal View History

2025-07-28 22:25:26 +02:00
#include "../src/container.hpp"
#include "../src/sorter.hpp"
#include <algorithm>
#include <chrono>
#include <cstddef>
#include <cstdint>
#include <iostream>
#include <random>
#include <string>
#include <string_view>
#include <vector>
namespace {
auto generate_uniform(std::size_t n) {
std::vector<std::uint64_t> input(n);
std::mt19937 gen(n);
std::uniform_int_distribution<std::uint64_t> dist;
std::ranges::generate(input, [&] { return dist(gen); });
return input;
}
void runExperiment(std::string_view rname,
2025-07-28 22:25:26 +02:00
auto container_factory,
auto sort_func,
int argc, char **argv) {
std::size_t n = 1e6;
std::size_t num_threads = 1;
int32_t radix_mode = 6;
2025-07-28 22:25:26 +02:00
if (argc >= 3) {
2025-07-28 22:25:26 +02:00
n = std::stol(argv[1]);
num_threads = std::stoi(argv[2]);
if (argc == 4) {
radix_mode = std::stoi(argv[3]);
}
2025-07-28 22:25:26 +02:00
} else {
// The number of threads is just here in case you want to parallelize your code.
// It's not currently used.
std::cerr << "Number of threads not specified!\n";
std::cerr << "Usage: " << argv[0] << " <n> <num_threads> [<radix_mode>]\n";
2025-07-28 22:25:26 +02:00
return;
}
std::ostringstream _name;
_name << "t" << num_threads << "r" << radix_mode;
std::string name = _name.str();
2025-07-28 22:25:26 +02:00
const auto input = generate_uniform(n);
const auto solution = [&] {
auto v = input;
std::ranges::sort(v);
return v;
}();
int iterations = 0;
long totalNanoseconds = 0;
long totalNanosecondsFactory = 0;
int maxIterations = 10'000;
while (totalNanoseconds < 1000 * 1000) {
if (iterations >= maxIterations) {
break;
}
std::chrono::steady_clock::time_point ctor = std::chrono::steady_clock::now();
auto to_sort = container_factory(input);
std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
sort_func(to_sort, num_threads, radix_mode);
2025-07-28 22:25:26 +02:00
std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
totalNanoseconds +=
std::chrono::duration_cast<std::chrono::nanoseconds>(end - begin)
.count();
totalNanosecondsFactory +=
std::chrono::duration_cast<std::chrono::nanoseconds>(begin - ctor)
.count();
iterations++;
if (not std::ranges::equal(to_sort.to_view(), solution)) {
std::cerr << "Output of " << name << " is not correct!\n";
return;
}
}
std::cout << "RESULT"
<< " name=" << name << " n=" << n << " t=" << num_threads << " r=" << radix_mode
2025-07-28 22:25:26 +02:00
<< " iterations=" << iterations
<< " durationNanoseconds=" << totalNanoseconds / iterations
<< " totalDurationNanoseconds=" << totalNanoseconds
<< " constructorNanoseconds=" << totalNanosecondsFactory / iterations
<< " totalConstructorNanoseconds=" << totalNanosecondsFactory
<< '\n';
}
} // unnamed namespace
int main(int argc, char **argv) {
runExperiment("sort",
[](const auto& data) {
return ae::container(data);
},
[](ae::container& data, auto num_threads, int32_t radix) {
ae::sorter(num_threads, data.size(), radix).sort(data);
2025-07-28 22:25:26 +02:00
}, argc, argv);
return 0;
}