Stable Z sort

This commit is contained in:
Charlie Malmqvist 2024-07-23 12:11:52 +02:00
parent 9338ec248b
commit fe3fea0c29
2 changed files with 9 additions and 12 deletions

View file

@ -120,6 +120,7 @@ int entry(int argc, char **argv) {
hammer_xform = m4_translate(hammer_xform, v3(-.25f, -.25f, 0)); hammer_xform = m4_translate(hammer_xform, v3(-.25f, -.25f, 0));
push_z_layer(1000001); push_z_layer(1000001);
draw_image_xform(hammer_image, hammer_xform, v2(.5f, .5f), COLOR_RED); draw_image_xform(hammer_image, hammer_xform, v2(.5f, .5f), COLOR_RED);
draw_image_xform(hammer_image, hammer_xform, v2(.25f, .25f), COLOR_GREEN);
pop_z_layer(); pop_z_layer();
Vector2 hover_position = v2_rotate_point_around_pivot(v2(-.5, -.5), v2(0, 0), (f32)now); Vector2 hover_position = v2_rotate_point_around_pivot(v2(-.5, -.5), v2(0, 0), (f32)now);

View file

@ -11,7 +11,6 @@
// At 21 bits I'm able to sort a completely randomized collection of 100k integers at around // At 21 bits I'm able to sort a completely randomized collection of 100k integers at around
// 8m cycles (or 2.5-2.6ms on my shitty laptop i5-11300H) // 8m cycles (or 2.5-2.6ms on my shitty laptop i5-11300H)
void radix_sort(void *collection, void *help_buffer, u64 item_count, u64 item_size, u64 sort_value_offset_in_item, u64 number_of_bits) { void radix_sort(void *collection, void *help_buffer, u64 item_count, u64 item_size, u64 sort_value_offset_in_item, u64 number_of_bits) {
local_persist const int RADIX = 256; local_persist const int RADIX = 256;
local_persist const int BITS_PER_PASS = 8; local_persist const int BITS_PER_PASS = 8;
local_persist const int MASK = (RADIX - 1); local_persist const int MASK = (RADIX - 1);
@ -20,6 +19,7 @@ void radix_sort(void *collection, void *help_buffer, u64 item_count, u64 item_si
const u64 SIGN_SHIFT = 1ULL << (number_of_bits - 1); const u64 SIGN_SHIFT = 1ULL << (number_of_bits - 1);
u64* count = (u64*)alloc(get_temporary_allocator(), RADIX * sizeof(u64)); u64* count = (u64*)alloc(get_temporary_allocator(), RADIX * sizeof(u64));
u64* prefix_sum = (u64*)alloc(get_temporary_allocator(), RADIX * sizeof(u64));
u8* items = (u8*)collection; u8* items = (u8*)collection;
u8* buffer = (u8*)help_buffer; u8* buffer = (u8*)help_buffer;
@ -32,30 +32,26 @@ void radix_sort(void *collection, void *help_buffer, u64 item_count, u64 item_si
for (u64 i = 0; i < item_count; ++i) { for (u64 i = 0; i < item_count; ++i) {
u64 sort_value = *(u64*)(items + i * item_size + sort_value_offset_in_item); u64 sort_value = *(u64*)(items + i * item_size + sort_value_offset_in_item);
sort_value += SIGN_SHIFT; // Transform the value to handle negative numbers sort_value += SIGN_SHIFT;
u32 digit = (sort_value >> shift) & MASK; u32 digit = (sort_value >> shift) & MASK;
++count[digit]; ++count[digit];
} }
u64 sum = 0; prefix_sum[0] = 0;
for (u32 i = 0; i < RADIX; ++i) { for (u32 i = 1; i < RADIX; ++i) {
u64 temp = count[i]; prefix_sum[i] = prefix_sum[i - 1] + count[i - 1];
count[i] = sum;
sum += temp;
} }
for (u64 i = 0; i < item_count; ++i) { for (u64 i = 0; i < item_count; ++i) {
u64 sort_value = *(u64*)(items + i * item_size + sort_value_offset_in_item); u64 sort_value = *(u64*)(items + i * item_size + sort_value_offset_in_item);
u64 transformed_value = sort_value + SIGN_SHIFT; // Transform the value to handle negative numbers u64 transformed_value = sort_value + SIGN_SHIFT;
u32 digit = (transformed_value >> shift) & MASK; u32 digit = (transformed_value >> shift) & MASK;
memcpy(buffer + count[digit] * item_size, items + i * item_size, item_size); memcpy(buffer + prefix_sum[digit] * item_size, items + i * item_size, item_size);
++count[digit]; ++prefix_sum[digit];
} }
memcpy(items, buffer, item_count * item_size); memcpy(items, buffer, item_count * item_size);
} }
dealloc(get_temporary_allocator(), count);
} }
void merge_sort(void *collection, void *help_buffer, u64 item_count, u64 item_size, int (*compare)(const void *, const void *)) { void merge_sort(void *collection, void *help_buffer, u64 item_count, u64 item_size, int (*compare)(const void *, const void *)) {