mirror of
https://github.com/Ed94/Odin.git
synced 2026-06-23 22:25:00 -07:00
big: Improve timing code.
This commit is contained in:
+42
-22
@@ -45,34 +45,53 @@ _SQR_TOOM_CUTOFF,
|
||||
print_timings :: proc() {
|
||||
fmt.printf("Timings:\n");
|
||||
for v, i in Timings {
|
||||
if v.c > 0 {
|
||||
avg := time.Duration(f64(v.t) / f64(v.c));
|
||||
if v.count > 0 {
|
||||
avg_ticks := time.Duration(f64(v.ticks) / f64(v.count));
|
||||
avg_cycles := f64(v.cycles) / f64(v.count);
|
||||
|
||||
avg_s: string;
|
||||
switch {
|
||||
case avg < time.Microsecond:
|
||||
avg_s = fmt.tprintf("%v ns", time.duration_nanoseconds(avg));
|
||||
case avg < time.Millisecond:
|
||||
avg_s = fmt.tprintf("%v µs", time.duration_microseconds(avg));
|
||||
case avg_ticks < time.Microsecond:
|
||||
avg_s = fmt.tprintf("%v ns / %v cycles", time.duration_nanoseconds(avg_ticks), avg_cycles);
|
||||
case avg_ticks < time.Millisecond:
|
||||
avg_s = fmt.tprintf("%v µs / %v cycles", time.duration_microseconds(avg_ticks), avg_cycles);
|
||||
case:
|
||||
avg_s = fmt.tprintf("%v ms", time.duration_milliseconds(avg));
|
||||
avg_s = fmt.tprintf("%v ms / %v cycles", time.duration_milliseconds(avg_ticks), avg_cycles);
|
||||
}
|
||||
|
||||
total_s: string;
|
||||
switch {
|
||||
case v.t < time.Microsecond:
|
||||
total_s = fmt.tprintf("%v ns", time.duration_nanoseconds(v.t));
|
||||
case v.t < time.Millisecond:
|
||||
total_s = fmt.tprintf("%v µs", time.duration_microseconds(v.t));
|
||||
case v.ticks < time.Microsecond:
|
||||
total_s = fmt.tprintf("%v ns / %v cycles", time.duration_nanoseconds(v.ticks), v.cycles);
|
||||
case v.ticks < time.Millisecond:
|
||||
total_s = fmt.tprintf("%v µs / %v cycles", time.duration_microseconds(v.ticks), v.cycles);
|
||||
case:
|
||||
total_s = fmt.tprintf("%v ms", time.duration_milliseconds(v.t));
|
||||
total_s = fmt.tprintf("%v ms / %v cycles", time.duration_milliseconds(v.ticks), v.cycles);
|
||||
}
|
||||
|
||||
fmt.printf("\t%v: %s (avg), %s (total, %v calls)\n", i, avg_s, total_s, v.c);
|
||||
fmt.printf("\t%v: %s (avg), %s (total, %v calls)\n", i, avg_s, total_s, v.count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@(deferred_in_out=_SCOPE_END)
|
||||
SCOPED_TIMING :: #force_inline proc(c: Category) -> (ticks: time.Tick, cycles: u64) {
|
||||
cycles = time.read_cycle_counter();
|
||||
ticks = time.tick_now();
|
||||
return;
|
||||
}
|
||||
_SCOPE_END :: #force_inline proc(c: Category, ticks: time.Tick, cycles: u64) {
|
||||
cycles_now := time.read_cycle_counter();
|
||||
ticks_now := time.tick_now();
|
||||
|
||||
Timings[c].ticks = time.tick_diff(ticks, ticks_now);
|
||||
Timings[c].cycles = cycles_now - cycles;
|
||||
Timings[c].count += 1;
|
||||
}
|
||||
SCOPED_COUNT_ADD :: #force_inline proc(c: Category, count: int) {
|
||||
Timings[c].count += count;
|
||||
}
|
||||
|
||||
Category :: enum {
|
||||
itoa,
|
||||
atoi,
|
||||
@@ -83,16 +102,16 @@ Category :: enum {
|
||||
ctz,
|
||||
bitfield_extract,
|
||||
};
|
||||
|
||||
Event :: struct {
|
||||
t: time.Duration,
|
||||
c: int,
|
||||
ticks: time.Duration,
|
||||
count: int,
|
||||
cycles: u64,
|
||||
}
|
||||
Timings := [Category]Event{};
|
||||
|
||||
print :: proc(name: string, a: ^Int, base := i8(10), print_name := true, newline := true, print_extra_info := false) {
|
||||
s := time.tick_now();
|
||||
as, err := itoa(a, base);
|
||||
Timings[.itoa].t += time.tick_since(s); Timings[.itoa].c += 1;
|
||||
|
||||
defer delete(as);
|
||||
cb, _ := count_bits(a);
|
||||
@@ -128,12 +147,13 @@ demo :: proc() {
|
||||
/*
|
||||
Timing loop
|
||||
*/
|
||||
s_old := time.tick_now();
|
||||
for o := 0; o < count - bits; o += 1 {
|
||||
be1, _ = int_bitfield_extract(a, o, bits);
|
||||
{
|
||||
SCOPED_TIMING(.bitfield_extract);
|
||||
for o := 0; o < count - bits; o += 1 {
|
||||
be1, _ = int_bitfield_extract(a, o, bits);
|
||||
}
|
||||
}
|
||||
Timings[.bitfield_extract].t += time.tick_since(s_old);
|
||||
Timings[.bitfield_extract].c += (count - bits);
|
||||
SCOPED_COUNT_ADD(.bitfield_extract, count - bits - 1);
|
||||
fmt.printf("be1: %v\n", be1);
|
||||
}
|
||||
|
||||
|
||||
+11
-26
@@ -205,19 +205,19 @@ int_bitfield_extract :: proc(a: ^Int, offset, count: int) -> (res: _WORD, err: E
|
||||
*/
|
||||
if count == 1 {
|
||||
limb := offset / _DIGIT_BITS;
|
||||
if limb < 0 || limb >= a.used { return 0, .Invalid_Argument; }
|
||||
if limb < 0 || limb >= a.used { return 0, .Invalid_Argument; }
|
||||
i := _WORD(1 << _WORD((offset % _DIGIT_BITS)));
|
||||
return 1 if ((_WORD(a.digit[limb]) & i) != 0) else 0, nil;
|
||||
}
|
||||
|
||||
if count > _WORD_BITS || count < 1 { return 0, .Invalid_Argument; }
|
||||
if count > _WORD_BITS || count < 1 { return 0, .Invalid_Argument; }
|
||||
|
||||
/*
|
||||
There are 3 possible cases.
|
||||
- [offset:][:count] covers 1 DIGIT,
|
||||
e.g. offset: 0, count: 60 = bits 0..59
|
||||
e.g. offset: 0, count: 60 = bits 0..59
|
||||
- [offset:][:count] covers 2 DIGITS,
|
||||
e.g. offset: 5, count: 60 = bits 5..59, 0..4
|
||||
e.g. offset: 5, count: 60 = bits 5..59, 0..4
|
||||
e.g. offset: 0, count: 120 = bits 0..59, 60..119
|
||||
- [offset:][:count] covers 3 DIGITS,
|
||||
e.g. offset: 40, count: 100 = bits 40..59, 0..59, 0..19
|
||||
@@ -230,41 +230,26 @@ int_bitfield_extract :: proc(a: ^Int, offset, count: int) -> (res: _WORD, err: E
|
||||
|
||||
num_bits := min(bits_left, _DIGIT_BITS - bits_offset);
|
||||
|
||||
// fmt.printf("offset: %v | count: %v\n\n", offset, count);
|
||||
// fmt.printf("left: %v | bits_offset: %v | limb: %v | num: %v\n\n", bits_left, bits_offset, limb, num_bits);
|
||||
|
||||
shift := offset % _DIGIT_BITS;
|
||||
mask := (_WORD(1) << uint(num_bits)) - 1;
|
||||
|
||||
// fmt.printf("shift: %v | mask: %v\n", shift, mask);
|
||||
// fmt.printf("d: %v\n", a.digit[limb]);
|
||||
|
||||
res = (_WORD(a.digit[limb]) >> uint(shift)) & mask;
|
||||
|
||||
// fmt.printf("res: %v\n", res);
|
||||
shift := offset % _DIGIT_BITS;
|
||||
mask := (_WORD(1) << uint(num_bits)) - 1;
|
||||
res = (_WORD(a.digit[limb]) >> uint(shift)) & mask;
|
||||
|
||||
bits_left -= num_bits;
|
||||
if bits_left == 0 { return res, nil; }
|
||||
|
||||
res_shift := num_bits;
|
||||
num_bits = min(bits_left, _DIGIT_BITS);
|
||||
mask = (1 << uint(num_bits)) - 1;
|
||||
|
||||
num_bits = min(bits_left, _DIGIT_BITS);
|
||||
mask = (1 << uint(num_bits)) - 1;
|
||||
|
||||
v := (_WORD(a.digit[limb + 1]) & mask) << uint(res_shift);
|
||||
res |= v;
|
||||
res |= (_WORD(a.digit[limb + 1]) & mask) << uint(res_shift);
|
||||
|
||||
bits_left -= num_bits;
|
||||
if bits_left == 0 { return res, nil; }
|
||||
|
||||
// fmt.printf("bits_left: %v | offset: %v | num: %v\n", bits_left, offset, num_bits);
|
||||
|
||||
mask = (1 << uint(bits_left)) - 1;
|
||||
res_shift += _DIGIT_BITS;
|
||||
|
||||
v = (_WORD(a.digit[limb + 2]) & mask) << uint(res_shift);
|
||||
res |= v;
|
||||
|
||||
res |= (_WORD(a.digit[limb + 2]) & mask) << uint(res_shift);
|
||||
|
||||
return res, nil;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user