dsimcha wrote:
== Quote from The Anh Tran ([EMAIL PROTECTED])'s article
Hi,
Could you measure spinlock with this bench?
http://shootout.alioth.debian.org/u32q/benchmark.php?test=binarytrees&lang=all
Thanks.
I tried to reply to your post last night with my modified gcx.d, but apparently
posting attachments of that size (~80kb) silently fails.
There is no multithreaded implementation of the binary trees benchmark for D
that
I was able to find. As far as the single-threaded version, spinlocks would make
absolutely no difference because the druntime GC uses thread_needLock() to avoid
any kind of lock on single-threaded code.
If you or anyone else wants to play around w/ my modified gcx.d code and try it
under different use cases, I've posted it to http://cis.jhu.edu/~dsimcha/gcx.d.
I've failed to recompile druntime with your gcx.d. I'm still a D newbie
:|. Ie: need someone to hold my hand and guide steps by steps ;)
This is my multithread alloc implementation.
If it uses std.gc, and runs with 2 threads; it is 5 times slower than 1
thread !???
// The Computer Language Benchmarks Game
// http://shootout.alioth.debian.org/
// By bearophile, optimized for simplicity, quite slow
// Run: testgc.exe xx yy
// xx: alloc depth, default is 14
// yy: how many threads, default is 1
// Ex: testgc.exe 18 4
import core.thread;
import core.memory;
import std.perf;
import std.stdio;
import std.conv;
import std.string;
import std.c.time;
import std.c.stdio;
class TreeNode
{
int item;
TreeNode left, right;
this(int item, TreeNode left =null, TreeNode right =null)
{
this.item = item;
this.left = left;
this.right = right;
}
~this()
{
if (left !is null)
{
delete left;
delete right;
}
}
int check() const
{
if (left !is null)
return (item + left.check - right.check);
else
return item;
}
static TreeNode makeTree(int item, int depth)
{
if (depth > 0)
return new TreeNode( item,
makeTree(2*item-1, depth-1),
makeTree(2*item, depth-1) );
else
return new TreeNode(item);
}
}
int fetch_job(int step)(int*)
{
asm
{
naked;
mov ECX, EAX; // last var pass on EAX
mov EAX, step;
lock;
xadd [ECX], EAX; // EAX = old value
ret;
}
}
void main(string[] args)
{
int n = (args.length >= 2) ? toInt(args[1]) : 14;
int nthreads = (args.length >= 3) ? toInt(args[2]) : 1;
const minDepth = 4;
int maxDepth = (minDepth + 2) > n ? minDepth + 2 : n;
GC.disable;
scope pc = new PerformanceCounter;
pc.start;
{
scope stretchTree = TreeNode.makeTree(0, maxDepth + 1);
writefln("stretch tree of depth ", maxDepth + 1, "\t check: ",
stretchTree.check);
}
{
scope longLivedTree = TreeNode.makeTree(0, maxDepth);
{
scope string[] result = new string[maxDepth +1];
scope Thread[] threads = new Thread[nthreads];
int current_depth = minDepth;
foreach (ref t; threads)
{
t = new Thread(
{
int depth;
while ((depth =
fetch_job!(2)(¤t_depth)) <= maxDepth)
//for (int depth = minDepth; depth <=
maxDepth; depth += 2)
{
int iterations = 1 << (maxDepth - depth
+ minDepth);
int check = 0;
for (int i = 1; i <= iterations; i++)
{
scope lt =
TreeNode.makeTree(i, depth);
scope rt =
TreeNode.makeTree(-i, depth);
check += lt.check + rt.check;
}
result[depth] = format("%d\t
trees of depth %d\t check: %d\n", iterations * 2, depth, check);
}
});
t.start;
}
foreach (t; threads)
t.join();
foreach (str; result)
writef(str);
}
writefln("long lived tree of depth ", maxDepth, "\t check: ",
longLivedTree.check);
}
pc.stop;
writefln("\nTiming: ", pc.milliseconds, " ms with ", nthreads, " threads");
}