package benchmark_runtime import "base:runtime" import "core:fmt" import "core:log" import "core:testing" import "core:strings" import "core:text/table" import "core:time" RUNS_PER_SIZE :: 2500 sizes := [?]int { 7, 8, 9, 15, 16, 17, 31, 32, 33, 63, 64, 65, 95, 96, 97, 128, 256, 512, 1024, 4096, 1024 * 1024, } // These are the normal, unoptimized algorithms. plain_memory_equal :: proc "contextless" (x, y: rawptr, n: int) -> bool { switch { case n == 0: return true case x == y: return true } a, b := ([^]byte)(x), ([^]byte)(y) length := uint(n) for i := uint(0); i < length; i += 1 { if a[i] != b[i] { return false } } return true } plain_memory_compare :: proc "contextless" (a, b: rawptr, n: int) -> int #no_bounds_check { switch { case a == b: return 0 case a == nil: return -1 case b == nil: return +1 } x := uintptr(a) y := uintptr(b) n := uintptr(n) SU :: size_of(uintptr) fast := n/SU + 1 offset := (fast-1)*SU curr_block := uintptr(0) if n < SU { fast = 0 } for /**/; curr_block < fast; curr_block += 1 { va := (^uintptr)(x + curr_block * size_of(uintptr))^ vb := (^uintptr)(y + curr_block * size_of(uintptr))^ if va ~ vb != 0 { for pos := curr_block*SU; pos < n; pos += 1 { a := (^byte)(x+pos)^ b := (^byte)(y+pos)^ if a ~ b != 0 { return -1 if (int(a) - int(b)) < 0 else +1 } } } } for /**/; offset < n; offset += 1 { a := (^byte)(x+offset)^ b := (^byte)(y+offset)^ if a ~ b != 0 { return -1 if (int(a) - int(b)) < 0 else +1 } } return 0 } plain_memory_compare_zero :: proc "contextless" (a: rawptr, n: int) -> int #no_bounds_check { x := uintptr(a) n := uintptr(n) SU :: size_of(uintptr) fast := n/SU + 1 offset := (fast-1)*SU curr_block := uintptr(0) if n < SU { fast = 0 } for /**/; curr_block < fast; curr_block += 1 { va := (^uintptr)(x + curr_block * size_of(uintptr))^ if va ~ 0 != 0 { for pos := curr_block*SU; pos < n; pos += 1 { a := (^byte)(x+pos)^ if a ~ 0 != 0 { return -1 if int(a) < 0 else +1 } } } } for /**/; offset < n; offset += 1 { a := (^byte)(x+offset)^ if a ~ 0 != 0 { return -1 if int(a) < 0 else +1 } } return 0 } run_trial_size_cmp :: proc(p: proc "contextless" (rawptr, rawptr, int) -> $R, size: int, idx: int, runs: int, loc := #caller_location) -> (timing: time.Duration) { left := make([]u8, size) right := make([]u8, size) defer { delete(left) delete(right) } right[idx] = 0x01 accumulator: int watch: time.Stopwatch time.stopwatch_start(&watch) for _ in 0.. int, size: int, idx: int, runs: int, loc := #caller_location) -> (timing: time.Duration) { data := make([]u8, size) defer delete(data) data[idx] = 0x01 accumulator: int watch: time.Stopwatch time.stopwatch_start(&watch) for _ in 0..