/** * Benchmark hash with cache stomping. * * Copyright: Copyright Martin Nowak 2015 - . * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Authors: Martin Nowak */ import std.file, std.algorithm, std.random, std.math; // exponential distribution around mean struct ExpRandom { double mean; Xorshift32 gen; this(double mean) { this.mean = mean; gen = Xorshift32(unpredictableSeed); } size_t front() { return cast(size_t)(mean * -log(uniform!"()"(0.0, 1.0, gen)) + 0.5); } alias gen this; } struct CacheStomper { ExpRandom rnd; size_t i; ubyte[] mem; this(size_t avgBytesPerCall) { rnd = ExpRandom(avgBytesPerCall / 64.0); mem = new ubyte[](32 * 1024 * 1024); } void stomp() { immutable n = rnd.front(); rnd.popFront(); foreach (_; 0 .. n) ++mem[(i += 64) & ($ - 1)]; } } void main(string[] args) { auto path = args.length > 1 ? args[1] : "extra-files/dante.txt"; auto words = splitter(cast(string) read(path), ' '); size_t[string] aa; auto stomper = CacheStomper(1000); foreach (_; 0 .. 10) { foreach (word; words) { ++aa[word]; stomper.stomp(); } } }