fixes divide by zero in mask.

This commit is contained in:
Patrick Schneider 2025-07-30 15:05:52 +02:00
parent 3bd8733411
commit 04789b5290
4 changed files with 25 additions and 18 deletions

View File

@ -8,7 +8,8 @@ from pathlib import Path
def run_experiment(output_file, build_dir): def run_experiment(output_file, build_dir):
# The number of threads is not currently used, it's just here in case you want to parallelize your code. # The number of threads is not currently used, it's just here in case you want to parallelize your code.
for threads in [1]: for threads in [1]:
for size in [1e2, 1e3, 1e4 + 1, 1e5, 1e6 - 1, 1e7]: # for size in [1e2, 1e3, 1e4 + 1, 1e5, 1e6 - 1, 1e7]:
for size in [1e2]:
print("Measuring p=" + str(threads) + " n=" + str(size)) print("Measuring p=" + str(threads) + " n=" + str(size))
executable = Path(build_dir) / "Sorter" executable = Path(build_dir) / "Sorter"
returncode = subprocess.call([executable, str(size), str(threads)], stdout=output_file) returncode = subprocess.call([executable, str(size), str(threads)], stdout=output_file)

0
result.txt Normal file
View File

View File

@ -4,6 +4,8 @@
#include <iterator> #include <iterator>
#include <cassert> #include <cassert>
#include <iostream> #include <iostream>
#include <bitset>
#include <climits>
namespace ae { namespace ae {
@ -21,46 +23,49 @@ void sorter::msd_inplace_radix_sort(
size_t passes, size_t passes,
const std::function<void(std::span<container::element_type> bucket)>& bucket_sort const std::function<void(std::span<container::element_type> bucket)>& bucket_sort
) { ) {
std::cerr << "passes: " << passes << std::endl; std::cerr << "passes: " << passes << "size: " << range.size() << std::endl;
if (sorter::RADIX_ITERATIONS == passes) { if (sorter::RADIX_ITERATIONS == passes) {
std::cerr << "going to robin " << *std::begin(range) << std::endl;
if (std::begin(range) + 1 < std::end(range)) {
bucket_sort(range); bucket_sort(range);
}
return; return;
} }
auto lower = std::begin(range); auto lower = std::begin(range);
auto upper = std::end(range); auto upper = std::end(range);
for (auto element = lower; element < std::end(range);) { for (auto element = lower; element < upper;) {
std::cerr << *element << " " << &*element << " " << &*lower << " " << &*upper << std::endl; std::cerr << *element << " " << &*element << " " << &*lower << " " << &*upper << std::endl;
// Mask out the <sorter::RADIX_ITERATIONS>-last bit and check if it is set // Mask out the <sorter::RADIX_ITERATIONS>-last bit and check if it is set
if ((*element & (1uz << sizeof(container::element_type) * 8 - passes))) { // std::cerr << std::bitset<64>((1L << (sizeof(container::element_type) * CHAR_BIT - passes - 1))) << std::endl;
// fprintf(stderr, "%lx\n", (1L << (sizeof(container::element_type) * CHAR_BIT - passes - 1)));
if ((*element & (1L << (sizeof(container::element_type) * CHAR_BIT - passes - 1)))) {
// The <passes> bit is set, so move to the beginning of the end section and decrement the upper iterator // The <passes> bit is set, so move to the beginning of the end section and decrement the upper iterator
std::swap(upper, element); std::swap(*upper, *element);
--upper; --upper;
} else { } else {
// The <passes> bit is unset, so move to the end of the beginning section and increment the upper iterator // The <passes> bit is unset, so move to the end of the beginning section and increment the upper iterator
std::swap(lower, element); std::swap(*lower, *element);
++lower; ++lower;
}
if (element < lower) {
++element; ++element;
} else if (element > upper) {
--element;
} }
} }
assert(lower == upper); // assert(lower == upper);
sorter::msd_inplace_radix_sort(std::span<container::element_type> (std::begin(range), lower), passes + 1, bucket_sort); sorter::msd_inplace_radix_sort(std::span<container::element_type> (std::begin(range), lower), passes + 1, bucket_sort);
sorter::msd_inplace_radix_sort(std::span<container::element_type> (upper, std::end(range)), passes + 1, bucket_sort); sorter::msd_inplace_radix_sort(std::span<container::element_type> (upper, std::end(range)), passes + 1, bucket_sort);
} }
void sorter::robin_hood_sort(std::span<container::element_type> bucket) { void sorter::robin_hood_sort(std::span<container::element_type> bucket) {
std::cerr << "robin hood lol" << std::endl;
const auto size = bucket.size() + sorter::OVERHEAD_SIZE; const auto size = bucket.size() + sorter::OVERHEAD_SIZE;
const size_t mask = ~(-1 >> sorter::RADIX_ITERATIONS); const auto mask = ((1L) << (sizeof(container::element_type) * CHAR_BIT - sorter::RADIX_ITERATIONS)) - 1;
container::element_type space[size]; container::element_type space[size];
std::cerr << "robin hood before loop" << std::endl;
for (auto element : bucket) { for (auto element : bucket) {
auto masked_element = (element & mask); auto masked_element = (element & mask);
auto index = masked_element * size/ mask; std::cerr << "robin hood elements " << element << " " << masked_element << " " << size << " " << mask << std::endl;
auto index = (masked_element * size) / mask;
std::cerr << "robin hood index " << index << " " << size << std::endl;
if (space[index] == -1) { if (space[index] == -1) {
space[index] = masked_element; space[index] = masked_element;
} else { } else {
@ -69,6 +74,7 @@ void sorter::robin_hood_sort(std::span<container::element_type> bucket) {
space[i] = masked_element; space[i] = masked_element;
} }
} }
std::cerr << "robin hood after loop" << std::endl;
// One final pass to correct linear probing errors // One final pass to correct linear probing errors
for (auto i = 1; i < size; ++i) { for (auto i = 1; i < size; ++i) {

View File

@ -16,8 +16,8 @@ class sorter {
const std::function<void(std::span<container::element_type> bucket)>& bucket_sort const std::function<void(std::span<container::element_type> bucket)>& bucket_sort
); );
const size_t OVERHEAD_SIZE = 100L; const uint32_t OVERHEAD_SIZE = 10L;
const size_t RADIX_ITERATIONS = 32; const uint32_t RADIX_ITERATIONS = 6;
void robin_hood_sort(std::span<container::element_type> range); void robin_hood_sort(std::span<container::element_type> range);
}; };