-
Notifications
You must be signed in to change notification settings - Fork 0
/
cache.zig
59 lines (47 loc) · 1.85 KB
/
cache.zig
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
//! Tests of memory hierarchy
const std = @import("std");
const metron = @import("metron");
const range = metron.range;
const ByteCounter = metron.ByteCounter;
const State = metron.State;
pub fn main() anyerror!void {
try metron.run(struct {
pub const name = "cache";
pub const args = range(usize, 2, 1 << 13, 1 << 26);
pub const arg_units = .div_1024;
pub const Counters = struct {
rate: ByteCounter(.div_1024) = .{},
};
// source: Chandler Carruth's CppCon 2017 talk
// https://www.youtube.com/watch?v=2EWejmkKlxs
pub fn do_bench(state: *State, bytes: usize) !Counters {
const count = bytes / @sizeOf(usize) / 2; // half for indices, half for data
const List = std.ArrayListAligned(usize, std.atomic.cache_line);
var prng = std.rand.DefaultPrng.init(0);
const random = prng.random();
var data = try List.initCapacity(state.alloc, count);
defer data.deinit();
var indx = try List.initCapacity(state.alloc, count);
defer indx.deinit();
data.expandToCapacity();
for (data.items) |*d| {
// generate a random usize [0, max(usize)]
d.* = random.int(usize);
}
indx.expandToCapacity();
for (indx.items) |*i| {
// generate a random index into data [0, count)
i.* = random.uintLessThan(usize, count);
}
var iter = state.iter();
while (iter.next()) |_| {
var sum: usize = 0;
for (indx.items) |i| {
sum = sum +% data.items[i];
}
std.mem.doNotOptimizeAway(sum);
}
return Counters{ .rate = .{ .val = bytes * state.iterations } };
}
});
}