add beginining of indirect sorting

This commit is contained in:
Brendan Hansknecht 2024-07-27 00:45:46 -07:00
parent 47017179a6
commit 0e092e0225
No known key found for this signature in database
GPG key ID: 0EA784685083E75B

View file

@ -46,10 +46,66 @@ pub fn quadsort(
// Then have our builtin dispatch to the correct version.
// llvm garbage collection would remove all other variants.
// Also, for numeric types, inlining the compare function can be a 2x perf gain.
if (element_width <= MAX_ELEMENT_BUFFER_SIZE) {
if (element_width <= MAX_ELEMENT_BUFFER_SIZE and false) {
quadsort_direct(source_ptr, len, cmp, cmp_data, data_is_owned, inc_n_data, element_width, alignment, copy);
} else {
roc_panic("todo: fallback to an indirect pointer sort", 0);
if (utils.alloc(len * @sizeOf(usize), @alignOf(usize))) |alloc_ptr| {
// Build list of pointers to sort.
if (@import("builtin").target.cpu.arch != .wasm32) {
std.debug.print("Allocated! filling array.\n", .{});
}
var arr_ptr = @as([*]Opaque, @ptrCast(@alignCast(alloc_ptr)));
defer utils.dealloc(alloc_ptr, @alignOf(usize));
for (0..len) |i| {
arr_ptr[i] = source_ptr + i * element_width;
}
// Create indirect compare function.
if (@import("builtin").target.cpu.arch != .wasm32) {
std.debug.print("Creating indirect sort!\n", .{});
}
const IndirectSort = struct {
compare: CompareFn,
pub fn indirect_compare(compare_data: Opaque, lhs_ptr: Opaque, rhs_ptr: Opaque) callconv(.C) u8 {
const lhs = @as(*Opaque, @ptrCast(@alignCast(lhs_ptr))).*;
const rhs = @as(*Opaque, @ptrCast(@alignCast(rhs_ptr))).*;
return compare(compare_data, lhs, rhs);
}
};
const indirect_sort = IndirectSort{ .compare = cmp };
// Sort.
if (@import("builtin").target.cpu.arch != .wasm32) {
std.debug.print("Sorting!\n", .{});
}
quadsort_direct(@ptrCast(arr_ptr), len, indirect_sort.compare, cmp_data, data_is_owned, inc_n_data, @sizeOf(usize), @alignOf(usize), &pointer_copy);
if (utils.alloc(len * element_width, alignment)) |collect_alloc_ptr| {
if (@import("builtin").target.cpu.arch != .wasm32) {
std.debug.print("Allocated2! Collecting\n", .{});
}
// Collect sorted pointers into correct order.
var collect_ptr = collect_alloc_ptr;
defer utils.dealloc(collect_alloc_ptr, alignment);
for (0..len) |i| {
copy(collect_ptr, arr_ptr[i]);
collect_ptr += element_width;
}
// Copy to original array as sorted.
if (@import("builtin").target.cpu.arch != .wasm32) {
std.debug.print("Copy out!\n", .{});
}
@memcpy(source_ptr[0..(len * element_width)], collect_ptr[0..(len * element_width)]);
if (@import("builtin").target.cpu.arch != .wasm32) {
std.debug.print("Sorted:[{d}]{d}\nAll done!\n", .{ len, @as([*]i64, @ptrCast(@alignCast(source_ptr)))[0..len] });
}
} else {
roc_panic("Out of memory while trying to allocate for sorting", 0);
}
} else {
roc_panic("Out of memory while trying to allocate for sorting", 0);
}
}
}
@ -2440,6 +2496,10 @@ test "swap" {
try testing.expectEqual(arr, [2]i64{ -22, -22 });
}
pub fn pointer_copy(dst_ptr: Opaque, src_ptr: Opaque) callconv(.C) void {
@as(*usize, @alignCast(@ptrCast(dst_ptr))).* = @as(*usize, @alignCast(@ptrCast(src_ptr))).*;
}
fn test_i64_compare(_: Opaque, a_ptr: Opaque, b_ptr: Opaque) callconv(.C) u8 {
const a = @as(*i64, @alignCast(@ptrCast(a_ptr))).*;
const b = @as(*i64, @alignCast(@ptrCast(b_ptr))).*;