Port a benchmark to D?
bearophile
bearophileHUGS at lycos.com
Sat Jun 4 13:00:38 PDT 2011
UnionFindNode struct instances probably doesn't need a memory pool, it's already allocated in (small) arrays.
I have not found a simple enough way to allocate SimpleLoop struct instances with a memory pool.
I have not found simple ways to use most of the C++ optimization hints of the original paper. The paper is badly written and its contents are worse. I think they have written this as an internal benchmark and only later have created a paper. I think they have used an old CPU because their PC farms often use similar old CPUs.
I have created a D version a bit de-optimized, that uses classes instead of structs for the classes that are instantiated only few times. Generally the original C++ code is not good: it's low level where it doesn't need to be low level, and it wastes memory and time where it matters (like in tiny data structures with lot of overhead.) I do not generally write code like that.
I don't have desire to work further on this code.
I'd like a Set with a very handy API (copied from Python) in Phobos.
I'd like the built-in associative arrays to have an optimization for very small number of items. Python dicts have an optimization for 8 items or less.
I have done no attempts to tune the GC. I confirm that if you disable the GC and perform a collection only once in a while, the code gets faster. Regarding the improvements of the D GC, I remember I have found an optimization for LDC1 lot of time ago, but I don't remember it well. I think the GC scans the static memory too, etc, this slows down the GC.
Google seems to care a lot about compilation times too. The D code compiles in about 1 second or less with full optimization. The C++0x code compiled with G++ doesn't come even close to that.
D code compiled with DMD 2.053 with:
dmd -O -release -inline -w -L/STACK:5000000
Using -g doesn't crash my code on Windows, so I suggest someone to minimize the code to find this bug.
I also suggest someone to minimize the code for the 64 version to find the 64 bit DMD bug.
C++0x code compiled with G++ 4.6 with:
g++ -std=c++0x -Ofast -Wall -Wextra -s
With LDC and GDC I suggest to look much better for the correct switches. Othrerwise this benchmark becomes even more meaningless (it's already not so meaningful. Google has not released the full C++ code).
I have created a D version that uses a TinySet, following one of the C++ optimization hints, one of the D versions use it, but I don't currently have a good PC to actually take the timings:
import std.typetuple: TypeTuple;
extern(C) pure nothrow void exit (in int status);
template Range(int stop) {
static if (stop <= 0)
alias TypeTuple!() Range;
else
alias TypeTuple!(Range!(stop-1), stop-1) Range;
}
struct TinySet(T, int maxLength) {
T[maxLength] data;
size_t length = 0; // readonly property
void add(T x) {
/*static*/ foreach (i; Range!maxLength)
if (x == data[i])
return;
if (length < maxLength) {
data[this.length] = x;
length++;
} else
exit(1);
}
T[] opSlice() {
return data[0 .. this.length];
}
}
C++0x code a bit modified, uses unordered_map instead of silly map:
http://codepad.org/9NEL9yPo
D code with structs and classes (no manual deallocations), less ugly, probably this is the version to show to people:
http://codepad.org/Xqg0Y26S
Experimental D code with TinySet, with structs and classes (no manual deallocations):
http://codepad.org/4ATOvFsV
D code with only structs (no manual deallocations):
http://codepad.org/SePFDAaT
D code with only classes:
http://codepad.org/k0DUzP3D
Bye,
bearophile
More information about the Digitalmars-d
mailing list