mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-04 22:58:46 +00:00
Add xxhash benchmark.
This commit is contained in:
@@ -11,6 +11,10 @@ package xxhash
|
|||||||
|
|
||||||
import "core:intrinsics"
|
import "core:intrinsics"
|
||||||
import "core:runtime"
|
import "core:runtime"
|
||||||
|
import "core:time"
|
||||||
|
import "core:fmt"
|
||||||
|
import "core:testing"
|
||||||
|
|
||||||
mem_copy :: runtime.mem_copy
|
mem_copy :: runtime.mem_copy
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -75,4 +79,85 @@ XXH64_read64 :: #force_inline proc(buf: []u8, alignment: Alignment) -> (res: u64
|
|||||||
mem_copy(&b, raw_data(buf[:]), 8)
|
mem_copy(&b, raw_data(buf[:]), 8)
|
||||||
return u64(b)
|
return u64(b)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Benchmarks
|
||||||
|
*/
|
||||||
|
|
||||||
|
setup_xxhash :: proc(options: ^time.Benchmark_Options, allocator := context.allocator) -> (err: time.Benchmark_Error) {
|
||||||
|
assert(options != nil)
|
||||||
|
|
||||||
|
options.input = make([]u8, options.bytes, allocator)
|
||||||
|
return nil if len(options.input) == options.bytes else .Allocation_Error
|
||||||
|
}
|
||||||
|
|
||||||
|
teardown_xxhash :: proc(options: ^time.Benchmark_Options, allocator := context.allocator) -> (err: time.Benchmark_Error) {
|
||||||
|
assert(options != nil)
|
||||||
|
|
||||||
|
delete(options.input)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
benchmark_xxhash32 :: proc(options: ^time.Benchmark_Options, allocator := context.allocator) -> (err: time.Benchmark_Error) {
|
||||||
|
buf := options.input
|
||||||
|
|
||||||
|
for _ in 0..=options.rounds {
|
||||||
|
_ = XXH32(buf)
|
||||||
|
}
|
||||||
|
options.count = options.rounds
|
||||||
|
options.processed = options.rounds * options.bytes
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
benchmark_xxhash64 :: proc(options: ^time.Benchmark_Options, allocator := context.allocator) -> (err: time.Benchmark_Error) {
|
||||||
|
buf := options.input
|
||||||
|
|
||||||
|
for _ in 0..=options.rounds {
|
||||||
|
_ = XXH64(buf)
|
||||||
|
}
|
||||||
|
options.count = options.rounds
|
||||||
|
options.processed = options.rounds * options.bytes
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
benchmark_print :: proc(name: string, options: ^time.Benchmark_Options) {
|
||||||
|
fmt.printf("\t[%v] %v rounds, %v bytes procesed in %v ns\n\t\t%5.3f rounds/s, %5.3f MiB/s\n",
|
||||||
|
name,
|
||||||
|
options.rounds,
|
||||||
|
options.processed,
|
||||||
|
time.duration_nanoseconds(options.duration),
|
||||||
|
options.rounds_per_second,
|
||||||
|
options.megabytes_per_second,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@test
|
||||||
|
benchmark_runner :: proc(t: ^testing.T) {
|
||||||
|
fmt.println("Starting benchmarks:")
|
||||||
|
|
||||||
|
options := &time.Benchmark_Options{
|
||||||
|
rounds = 1_000,
|
||||||
|
bytes = 100,
|
||||||
|
setup = setup_xxhash,
|
||||||
|
bench = benchmark_xxhash32,
|
||||||
|
teardown = teardown_xxhash,
|
||||||
|
}
|
||||||
|
err := time.benchmark(options, context.allocator)
|
||||||
|
benchmark_print("xxhash32 100 bytes", options)
|
||||||
|
|
||||||
|
options.bytes = 1_000_000
|
||||||
|
err = time.benchmark(options, context.allocator)
|
||||||
|
benchmark_print("xxhash32 1_000_000 bytes", options)
|
||||||
|
|
||||||
|
options.bytes = 100
|
||||||
|
options.bench = benchmark_xxhash64
|
||||||
|
err = time.benchmark(options, context.allocator)
|
||||||
|
benchmark_print("xxhash64 100 bytes", options)
|
||||||
|
|
||||||
|
options.bytes = 1_000_000
|
||||||
|
err = time.benchmark(options, context.allocator)
|
||||||
|
benchmark_print("xxhash64 1_000_000 bytes", options)
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package time
|
package time
|
||||||
|
|
||||||
|
import "core:mem"
|
||||||
|
|
||||||
Tick :: struct {
|
Tick :: struct {
|
||||||
_nsec: i64, // relative amount
|
_nsec: i64, // relative amount
|
||||||
}
|
}
|
||||||
@@ -37,3 +39,58 @@ SCOPED_TICK_DURATION :: proc(d: ^Duration) -> Tick {
|
|||||||
_tick_duration_end :: proc(d: ^Duration, t: Tick) {
|
_tick_duration_end :: proc(d: ^Duration, t: Tick) {
|
||||||
d^ = tick_since(t)
|
d^ = tick_since(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Benchmark helpers
|
||||||
|
*/
|
||||||
|
|
||||||
|
Benchmark_Error :: enum {
|
||||||
|
Okay = 0,
|
||||||
|
Allocation_Error,
|
||||||
|
}
|
||||||
|
|
||||||
|
Benchmark_Options :: struct {
|
||||||
|
setup: #type proc(options: ^Benchmark_Options, allocator: mem.Allocator) -> (err: Benchmark_Error),
|
||||||
|
bench: #type proc(options: ^Benchmark_Options, allocator: mem.Allocator) -> (err: Benchmark_Error),
|
||||||
|
teardown: #type proc(options: ^Benchmark_Options, allocator: mem.Allocator) -> (err: Benchmark_Error),
|
||||||
|
|
||||||
|
rounds: int,
|
||||||
|
bytes: int,
|
||||||
|
input: []u8,
|
||||||
|
|
||||||
|
count: int,
|
||||||
|
processed: int,
|
||||||
|
output: []u8,
|
||||||
|
|
||||||
|
/*
|
||||||
|
Performance
|
||||||
|
*/
|
||||||
|
duration: Duration,
|
||||||
|
rounds_per_second: f64,
|
||||||
|
megabytes_per_second: f64,
|
||||||
|
}
|
||||||
|
|
||||||
|
benchmark :: proc(options: ^Benchmark_Options, allocator := context.allocator) -> (err: Benchmark_Error) {
|
||||||
|
assert(options != nil)
|
||||||
|
assert(options.bench != nil)
|
||||||
|
|
||||||
|
if options.setup != nil {
|
||||||
|
options->setup(allocator) or_return
|
||||||
|
}
|
||||||
|
|
||||||
|
diff: Duration
|
||||||
|
{
|
||||||
|
SCOPED_TICK_DURATION(&diff)
|
||||||
|
options->bench(allocator) or_return
|
||||||
|
}
|
||||||
|
options.duration = diff
|
||||||
|
|
||||||
|
times_per_second := f64(Second) / f64(diff)
|
||||||
|
options.rounds_per_second = times_per_second * f64(options.count)
|
||||||
|
options.megabytes_per_second = f64(options.processed) / f64(1024 * 1024) * times_per_second
|
||||||
|
|
||||||
|
if options.teardown != nil {
|
||||||
|
options->teardown(allocator) or_return
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
@@ -24,7 +24,8 @@ _tick_now :: proc() -> Tick {
|
|||||||
return q * num + r * num / den
|
return q * num + r * num / den
|
||||||
}
|
}
|
||||||
|
|
||||||
@thread_local qpc_frequency: win32.LARGE_INTEGER
|
// @thread_local qpc_frequency: win32.LARGE_INTEGER
|
||||||
|
qpc_frequency: win32.LARGE_INTEGER
|
||||||
|
|
||||||
if qpc_frequency == 0 {
|
if qpc_frequency == 0 {
|
||||||
win32.QueryPerformanceFrequency(&qpc_frequency)
|
win32.QueryPerformanceFrequency(&qpc_frequency)
|
||||||
|
|||||||
Reference in New Issue
Block a user