Re: [computer-go] Random weighted patterns

2009-07-20 Thread Isaac Deutsch
I'm about to implement this. Since I have multiple features (patterns,  
is in atari, is adjacent to last play, etc.), the weight is the  
product of the weight of all matching features.


I'm thinking about having a table of weights, storing the sum of each  
row and the total (like Rémi suggested). I want to do this  
incrementally, so if I find a new feature match in a position, I can  
multiply its weight by the feature's weight. If I remove a feature, I  
can divide.


My question/problem: How do I deal with features that have a weight of  
zero? I'm sure there are certain 3x3 patterns that have the weight  
zero, such as


###
#*.
#..

with * to be played. It's clear that when this pattern matches, the  
total weight is set to zero. How do I find the resulting weight when  
removing this pattern, though? Since I can't divide by zero, I would  
have to reconstruct the weight by checking all features, which would  
be relatively slow. Is there a way this can be avoided, such as  
setting all weights to a very low value instead of zero?


Regards,
Isaac___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/

Re: [computer-go] Random weighted patterns

2009-07-20 Thread Juho Pennanen

Isaac Deutsch kirjoitti:
My question/problem: How do I deal with features that have a weight of 
zero? I'm sure there are certain 3x3 patterns that have the weight zero, 
such as


###
#*.
#..

with * to be played. It's clear that when this pattern matches, the 
total weight is set to zero. 


Hmm. Say this is a black group, surrounded by white stones and involved 
in an unsettled semeai:



#..#
#..#


W needs to play in one of the liberties, and they all match your pattern.

JP


___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/


Re: [computer-go] Random weighted patterns

2009-07-20 Thread Isaac Deutsch
In my example, #=border/edge of the board, not black. I was just  
trying to come up with an example feature that might have weight zero  
to illustrate my problem.

___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/


Re: [computer-go] Random weighted patterns

2009-07-20 Thread Juho Pennanen

Isaac Deutsch kirjoitti:
In my example, #=border/edge of the board, not black. I was just trying 
to come up with an example feature that might have weight zero to 
illustrate my problem.


I see. I was already thinking there may be no 3x3 patterns that should 
never be played. But I cannot think of a counter example to your corner 
case.


Assuming your multiplicative weighting is the best way in the first 
place, then the epsilon-sized minimum weight seems reasonable.


JP


___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/


Re: [computer-go] Random weighted patterns

2009-07-20 Thread Gunnar Farnebäck

Isaac Deutsch wrote:
 I'm about to implement this. Since I have multiple features
 (patterns, is in atari, is adjacent to last play, etc.), the weight
 is the product of the weight of all matching features.

 I'm thinking about having a table of weights, storing the sum of
 each row and the total (like Rémi suggested). I want to do this
 incrementally, so if I find a new feature match in a position, I can
 multiply its weight by the feature's weight. If I remove a feature,
 I can divide.

 My question/problem: How do I deal with features that have a weight
 of zero? I'm sure there are certain 3x3 patterns that have the
 weight zero, such as

 ###
 #*.
 #..

 with * to be played. It's clear that when this pattern matches, the
 total weight is set to zero. How do I find the resulting weight when
 removing this pattern, though? Since I can't divide by zero, I would
 have to reconstruct the weight by checking all features, which would
 be relatively slow. Is there a way this can be avoided, such as
 setting all weights to a very low value instead of zero?

Cache what features you have, then recomputing the weight will be fast.

GNU Go incrementally keeps track of the following features:

Black suicide (true/false)
White suicide (true/false)
Black self-atari (true/false)
White self-atari (true/false)
Number of stones captured by black move (0, 1, 2, 3+)
Number of stones captured by white move (0, 1, 2, 3+)
Color to the southeast (empty, white, black, off board)
Color to the northeast (empty, white, black, off board)
Color to the northwest (empty, white, black, off board)
Color to the southwest (empty, white, black, off board)
Color to the east (empty, white, black, off board)
Color to the north (empty, white, black, off board)
Color to the west (empty, white, black, off board)
Color to the south (empty, white, black, off board)

This information is stored in 24 bits of an integer. The 16 bits
related to the local 3x3 pattern are mapped by table lookup to the
1107 rotation/mirroring invariant patterns. The remaining 8 bits are
mapped to the following features:

Opponent suicide (1 bit)
Our self-atari (1 bit)
Opponent self-atari (1 bit)
Our captures (2 bits)
Opponent captures (2 bits)

by simple bit transposition depending on color to play. Additionally
nearness to the previous move is added as a feature giving 1107*256
combinations, which are finally mapped to pattern weight by table
lookup.

/Gunnar
___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/


Re: [computer-go] Random weighted patterns

2009-07-20 Thread Isaac Deutsch
Thanks to both for the elaborate feedback! I was wondering about  
pattern symmetry, too, and I also had a lookup table in mind since  
there are only about 65000 combinations (and only a fraction of them  
legal).


I had another idea for the zero weight problem: Keep a counter of how  
many times this weight was multiplied by zero. This counter can be  
stored in 1 byte or less, depending on the number of features. If the  
counter is 0, the weight is the floating point value. Else, the weight  
is zero. When adding a zero-weight-feature, increase the counter by  
one, else decrease it by one.


This way, the weight doesn't have to be recomputed, although it uses  
slightly more memory than nicely packing the features in an int like  
in GNU Go. It seems like the rounding errors that are accumulated this  
way are insignificant, according to my tests.

___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/


Re: [computer-go] Random weighted patterns

2009-07-16 Thread Steve Kroon

This code should work with r -= weights[i++] in the loop body, and comes down 
to a linear search through
cumulative sum of the weights.  If the weights will be static for a number of 
selections, you can store the
cumulative weights in an array and use binary search for selecting the move.  
So setting up the table is O(n),
but selecting moves based on those weights is O(log n).

If the weights are constantly being updated, there's a tradeoff between Peter's 
code and the tree-based approach:
Peter's code is O(1) for updating weights and O(n) for selections, while the 
tree-based approach is O(log n) for updates
and selections.

[You can get practically quicker selection using Peter's code if you keep the 
weights sorted in decreasing order, but then updates
become O(n) worst-case (probably O(1) amortized, though).]

Steve


On Thu, 16 Jul 2009, Don Dailey wrote:


In the loop i is always zero.   I think your code is wrong.

You probably meant to loop over all the weights (or I should say on average 
half the weights),  and this code is slow if there are a lot of weights.

2009/7/16 Peter Drake dr...@lclark.edu
  I must be missing something. Isn't the obvious trick:
int r = random(sum of weights);
int i = 0;
while (r  weights[i]) {
r -= weights[i];
}
return i;

This way, you only have to generate one random number.

Peter Drake
http://www.lclark.edu/~drake/



On Jul 15, 2009, at 8:55 PM, Zach Wegner wrote:

  On Wed, Jul 15, 2009 at 10:37 PM, David Fotlandfotl...@smart-games.com 
wrote:
So many complex ideas :)  Why not just multiply the weight of each 
pattern

by a random number and pick the biggest result?


David


  That involves generating N random numbers and then doing N-1
  comparisons. The n-ary tree has only 1 random number and log N
  comparisons, but has to be
  incrementally updated (log N adds).

  Also, I don't think the distribution is the same. Imagine two moves a
  and b, with weights 2 and 1. The probabilities should be a=2/3 b=1/3,
  but if you select two random numbers in a finite range, there's only a
  1/4 chance that the second number is more than twice the first, which
  is needed for b to be selected. I could be wrong here though.

  Zach
  ___
  computer-go mailing list
  computer-go@computer-go.org
  http://www.computer-go.org/mailman/listinfo/computer-go/



___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/






--
Steve Kroon | Computer Science Division, Stellenbosch University
(084) 458 8062 (Cell) | (086) 655 4386 (Fax) | kroonrs (Skype)
http://www.cs.sun.ac.za/~kroon | kr...@sun.ac.za___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/

Re: [computer-go] Random weighted patterns

2009-07-16 Thread George Dahl
Thanks! I had never seen the alias method before and it is quite ingenious!
- George

On Thu, Jul 16, 2009 at 3:04 AM, Martin Muellermmuel...@cs.ualberta.ca wrote:
 If you want to take many samples from a fixed, or infrequently changing,
 distribution, you can do it in O(1) time per sample, with O(n) initial setup
 costs. This is quite clever and goes by the name of alias method.
 See http://cg.scs.carleton.ca/~luc/rnbookindex.html, page 107-111

 For weighted patterns, the row sum method by Rémi is probably hard to beat.
 It was discussed here a while ago.

        Martin
 ___
 computer-go mailing list
 computer-go@computer-go.org
 http://www.computer-go.org/mailman/listinfo/computer-go/

___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/


Re: [computer-go] Random weighted patterns

2009-07-15 Thread Darren Cook
 When using patterns during the playout I had improvised some code to
 select patterns randomly, but favour those with higher weights more or
 less proportionally to the weight..

How many patterns, and are the weights constant for the whole game?

If relatively few, and constant, you can make a lookup table (with e.g.
1024 entries) where the number of entries for each pattern is
proportional to its weight. You then choose with a 0..1023 random number.

When more patterns, but only a few distinct weights you can split them
into buckets. E.g. a bucket of weight 1 patterns, weight 1.5 patterns,
weight 2 patterns, etc. The weight of each bucket is the number of
patterns in it times the pattern weight. You first choose a bucket (e.g.
using the above lookup table algorithm), then choose uniformly from
within the bucket.

Darren

P.S.  I suspect you have already came up with the above algorithms. I
had the same question before, and like you realized it wasn't quite as
easy as I thought it would be. I'd also like to hear what the standard
computer science approach is, if there is one. (I just saw Jason's
reply; do you have a good reference describing row sum in more detail?)


-- 
Darren Cook, Software Researcher/Developer
http://dcook.org/gobet/  (Shodan Go Bet - who will win?)
http://dcook.org/mlsn/ (Multilingual open source semantic network)
http://dcook.org/work/ (About me and my work)
http://dcook.org/blogs.html (My blogs and articles)
___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/


Re: [computer-go] Random weighted patterns

2009-07-15 Thread Peter Drake
You might look in the genetic algorithm literature, where they have to  
do this for fitness-proportional reproduction. A useful buzzword is  
roulette wheel.


Peter Drake
http://www.lclark.edu/~drake/



On Jul 15, 2009, at 4:06 PM, Mark Boon wrote:


When using patterns during the playout I had improvised some code to
select patterns randomly, but favour those with higher weights more or
less proportionally to the weight..

I was wondering though if there's an established algorithm for
something like this. To be a little more precise, if I have a set of
values and two of those are represented by A and B. If A is twice as
high as B it should have twice the chance to be selected. If there's a
third value C that is 1.5 times A then it should be 1.5 times as
likely to be selected as A and 3 times as likely as B. Etc.

There are many strategies I can think of that make a randomly weighted
selection from a set. But none of them are really straightforward. So
I'd be interested to hear how others handled something like this. And
if there's maybe a standard known algorithm, this kind of thing must
appear in a lot of fields.

Mark
___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/


___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/

Re: [computer-go] Random weighted patterns

2009-07-15 Thread Michael Williams

If your weights are all between 0 and 1:

do
   double r = rand(0 to 1)
   int i = rand(0 to weightCount - 1)
until weight[i]  r

I think that's right.


Mark Boon wrote:

When using patterns during the playout I had improvised some code to
select patterns randomly, but favour those with higher weights more or
less proportionally to the weight..

I was wondering though if there's an established algorithm for
something like this. To be a little more precise, if I have a set of
values and two of those are represented by A and B. If A is twice as
high as B it should have twice the chance to be selected. If there's a
third value C that is 1.5 times A then it should be 1.5 times as
likely to be selected as A and 3 times as likely as B. Etc.

There are many strategies I can think of that make a randomly weighted
selection from a set. But none of them are really straightforward. So
I'd be interested to hear how others handled something like this. And
if there's maybe a standard known algorithm, this kind of thing must
appear in a lot of fields.

Mark
___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/



___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/


Re: [computer-go] Random weighted patterns

2009-07-15 Thread Don Dailey
I think you could do this with a binary tree - at each node keep a total of
the weight values of the subtree below the node.

If the pattern was hashed, then each bit could define a branch of the tree,
0 = left branch 1 = right branch.

Then you have a very simple divide and conquer algorithm.   The tree would
not be perfectly balanced, but even with a lousy (fast) hash function it
would be more than adequate. You could have a massive populations of
things to select from probabilistically and this would still be very fast.

- Don



On Wed, Jul 15, 2009 at 7:06 PM, Mark Boon tesujisoftw...@gmail.com wrote:

 When using patterns during the playout I had improvised some code to
 select patterns randomly, but favour those with higher weights more or
 less proportionally to the weight..

 I was wondering though if there's an established algorithm for
 something like this. To be a little more precise, if I have a set of
 values and two of those are represented by A and B. If A is twice as
 high as B it should have twice the chance to be selected. If there's a
 third value C that is 1.5 times A then it should be 1.5 times as
 likely to be selected as A and 3 times as likely as B. Etc.

 There are many strategies I can think of that make a randomly weighted
 selection from a set. But none of them are really straightforward. So
 I'd be interested to hear how others handled something like this. And
 if there's maybe a standard known algorithm, this kind of thing must
 appear in a lot of fields.

 Mark
 ___
 computer-go mailing list
 computer-go@computer-go.org
 http://www.computer-go.org/mailman/listinfo/computer-go/

___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/

RE: [computer-go] Random weighted patterns

2009-07-15 Thread David Fotland
So many complex ideas :)  Why not just multiply the weight of each pattern
by a random number and pick the biggest result?

David

 -Original Message-
 From: computer-go-boun...@computer-go.org [mailto:computer-go-
 boun...@computer-go.org] On Behalf Of Mark Boon
 Sent: Wednesday, July 15, 2009 4:07 PM
 To: computer-go
 Subject: [computer-go] Random weighted patterns
 
 When using patterns during the playout I had improvised some code to
 select patterns randomly, but favour those with higher weights more or
 less proportionally to the weight..
 
 I was wondering though if there's an established algorithm for
 something like this. To be a little more precise, if I have a set of
 values and two of those are represented by A and B. If A is twice as
 high as B it should have twice the chance to be selected. If there's a
 third value C that is 1.5 times A then it should be 1.5 times as
 likely to be selected as A and 3 times as likely as B. Etc.
 
 There are many strategies I can think of that make a randomly weighted
 selection from a set. But none of them are really straightforward. So
 I'd be interested to hear how others handled something like this. And
 if there's maybe a standard known algorithm, this kind of thing must
 appear in a lot of fields.
 
 Mark
 ___
 computer-go mailing list
 computer-go@computer-go.org
 http://www.computer-go.org/mailman/listinfo/computer-go/

___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/


Re: [computer-go] Random weighted patterns

2009-07-15 Thread Darren Cook
 So many complex ideas :)  Why not just multiply the weight of each pattern
 by a random number and pick the biggest result?

Good for 5 patterns, not so good for 5000 patterns.

Darren

___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/


RE: [computer-go] Random weighted patterns

2009-07-15 Thread David Fotland
You would only do this for patterns that match in a position.  For Many
Faces that is typically a few dozen.  Many Faces only has about 1800 total
patterns in its go knowledge base.  Playouts use Mogo patterns, about a
dozen total.

David

 -Original Message-
 From: computer-go-boun...@computer-go.org [mailto:computer-go-
 boun...@computer-go.org] On Behalf Of Darren Cook
 Sent: Wednesday, July 15, 2009 8:47 PM
 To: computer-go
 Subject: Re: [computer-go] Random weighted patterns
 
  So many complex ideas :)  Why not just multiply the weight of each
 pattern
  by a random number and pick the biggest result?
 
 Good for 5 patterns, not so good for 5000 patterns.
 
 Darren
 
 ___
 computer-go mailing list
 computer-go@computer-go.org
 http://www.computer-go.org/mailman/listinfo/computer-go/

___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/


Re: [computer-go] Random weighted patterns

2009-07-15 Thread Zach Wegner
On Wed, Jul 15, 2009 at 10:37 PM, David Fotlandfotl...@smart-games.com wrote:
 So many complex ideas :)  Why not just multiply the weight of each pattern
 by a random number and pick the biggest result?

 David

That involves generating N random numbers and then doing N-1
comparisons. The n-ary tree has only 1 random number and log N
comparisons, but has to be
incrementally updated (log N adds).

Also, I don't think the distribution is the same. Imagine two moves a
and b, with weights 2 and 1. The probabilities should be a=2/3 b=1/3,
but if you select two random numbers in a finite range, there's only a
1/4 chance that the second number is more than twice the first, which
is needed for b to be selected. I could be wrong here though.

Zach
___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/


Re: [computer-go] Random weighted patterns

2009-07-15 Thread Peter Drake

I must be missing something. Isn't the obvious trick:

int r = random(sum of weights);
int i = 0;
while (r  weights[i]) {
r -= weights[i];
}
return i;

This way, you only have to generate one random number.

Peter Drake
http://www.lclark.edu/~drake/



On Jul 15, 2009, at 8:55 PM, Zach Wegner wrote:

On Wed, Jul 15, 2009 at 10:37 PM, David Fotlandfotl...@smart-games.com 
 wrote:
So many complex ideas :)  Why not just multiply the weight of each  
pattern

by a random number and pick the biggest result?

David


That involves generating N random numbers and then doing N-1
comparisons. The n-ary tree has only 1 random number and log N
comparisons, but has to be
incrementally updated (log N adds).

Also, I don't think the distribution is the same. Imagine two moves a
and b, with weights 2 and 1. The probabilities should be a=2/3 b=1/3,
but if you select two random numbers in a finite range, there's only a
1/4 chance that the second number is more than twice the first, which
is needed for b to be selected. I could be wrong here though.

Zach
___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/


___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/

Re: [computer-go] Random weighted patterns

2009-07-15 Thread Don Dailey
In the loop i is always zero.   I think your code is wrong.

You probably meant to loop over all the weights (or I should say on average
half the weights),  and this code is slow if there are a lot of weights.

2009/7/16 Peter Drake dr...@lclark.edu

 I must be missing something. Isn't the obvious trick:
 int r = random(sum of weights);
 int i = 0;
 while (r  weights[i]) {
 r -= weights[i];
 }
 return i;

 This way, you only have to generate one random number.

 Peter Drake
 http://www.lclark.edu/~drake/ http://www.lclark.edu/%7Edrake/



 On Jul 15, 2009, at 8:55 PM, Zach Wegner wrote:

 On Wed, Jul 15, 2009 at 10:37 PM, David Fotlandfotl...@smart-games.com
 wrote:

 So many complex ideas :)  Why not just multiply the weight of each pattern

 by a random number and pick the biggest result?


 David


 That involves generating N random numbers and then doing N-1
 comparisons. The n-ary tree has only 1 random number and log N
 comparisons, but has to be
 incrementally updated (log N adds).

 Also, I don't think the distribution is the same. Imagine two moves a
 and b, with weights 2 and 1. The probabilities should be a=2/3 b=1/3,
 but if you select two random numbers in a finite range, there's only a
 1/4 chance that the second number is more than twice the first, which
 is needed for b to be selected. I could be wrong here though.

 Zach
 ___
 computer-go mailing list
 computer-go@computer-go.org
 http://www.computer-go.org/mailman/listinfo/computer-go/



 ___
 computer-go mailing list
 computer-go@computer-go.org
 http://www.computer-go.org/mailman/listinfo/computer-go/

___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/

Re: [computer-go] Random weighted patterns

2009-07-15 Thread Don Dailey
On Wed, Jul 15, 2009 at 11:37 PM, David Fotland fotl...@smart-games.comwrote:

 So many complex ideas :)  Why not just multiply the weight of each pattern
 by a random number and pick the biggest result?


This is fine if you are looking for the slowest algorithm you can find.
But it does have the merit of being straightforward, which is what he was
asking for.

The binary approach is O(log n) time on average, very efficient.   Your
approach is O(n).   It's like the difference between doing a binary search
to find something or scanning the whole list sequentially.

If you are looking at less than 5 or 10 patterns there may not be much
difference, but I assumed he was choosing among many patterns.

- Don





 David

  -Original Message-
  From: computer-go-boun...@computer-go.org [mailto:computer-go-
  boun...@computer-go.org] On Behalf Of Mark Boon
  Sent: Wednesday, July 15, 2009 4:07 PM
  To: computer-go
  Subject: [computer-go] Random weighted patterns
 
  When using patterns during the playout I had improvised some code to
  select patterns randomly, but favour those with higher weights more or
  less proportionally to the weight..
 
  I was wondering though if there's an established algorithm for
  something like this. To be a little more precise, if I have a set of
  values and two of those are represented by A and B. If A is twice as
  high as B it should have twice the chance to be selected. If there's a
  third value C that is 1.5 times A then it should be 1.5 times as
  likely to be selected as A and 3 times as likely as B. Etc.
 
  There are many strategies I can think of that make a randomly weighted
  selection from a set. But none of them are really straightforward. So
  I'd be interested to hear how others handled something like this. And
  if there's maybe a standard known algorithm, this kind of thing must
  appear in a lot of fields.
 
  Mark
  ___
  computer-go mailing list
  computer-go@computer-go.org
  http://www.computer-go.org/mailman/listinfo/computer-go/

 ___
 computer-go mailing list
 computer-go@computer-go.org
 http://www.computer-go.org/mailman/listinfo/computer-go/

___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/

Re: [computer-go] Random

2008-05-20 Thread A van Kessel
A reasonable xor+shift random (similar to Marsaglia's, but only 64bit
instead of 128 bits), using the pentium's rdtsc-instrunction to add
additional entropy (i used gnu's inline assembler) :::

#define rdtscll(val) \
  __asm__ __volatile__(rdtsc : =A (val))

typedef unsigned long long BIGTHING;
BIGTHING rdtsc_rand(void);

/**/
BIGTHING rdtsc_rand(void)
{
static BIGTHING val=0xULL;
BIGTHING new;

rdtscll(new);
val ^= (val  15) ^ (val  14) ^ 9 ^ new;

return val;
}
/**/

The extra ^9 at the end can be omitted if the new is nonzero.
(is only meant to avoid the val becoming all-zeros. And shifting zeros won't
change the value ;-)

HTH,
AvK
___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/


Re: [computer-go] Random

2008-05-20 Thread Don Dailey
The question I have is how much does RDTSC slow this down?I may do 
some tests to see.


- Don


A van Kessel wrote:

A reasonable xor+shift random (similar to Marsaglia's, but only 64bit
instead of 128 bits), using the pentium's rdtsc-instrunction to add
additional entropy (i used gnu's inline assembler) :::

#define rdtscll(val) \
  __asm__ __volatile__(rdtsc : =A (val))

typedef unsigned long long BIGTHING;
BIGTHING rdtsc_rand(void);

/**/
BIGTHING rdtsc_rand(void)
{
static BIGTHING val=0xULL;
BIGTHING new;

rdtscll(new);
val ^= (val  15) ^ (val  14) ^ 9 ^ new;

return val;
}
/**/

The extra ^9 at the end can be omitted if the new is nonzero.
(is only meant to avoid the val becoming all-zeros. And shifting zeros won't
change the value ;-)

HTH,
AvK
___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/

  

___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/


Re: [computer-go] Random

2008-05-20 Thread A van Kessel
 The question I have is how much does RDTSC slow this down?I may do 
I don't know.
If I understand correctly, rdtsc can be executed in parallen with *some*
other instructions (and places no barrier in the code), in which case
it could be executed at no additional cost (except the instruction fetching,
of course)
I have not yet been able to instruct GCC to use the mmx or sse3 instructions/
registers to do the shifting. Code could be reshuffeled to allow the
compiler more freedom.

AvK
___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/


Re: [computer-go] Random

2008-05-20 Thread Don Dailey
I did a simple test.   I compiled this version and the version below to 
get a sense of how fast it is.


Your version with RDTSC is quite slow compared to the version below.
I determined that RDTSC is taking almost all the time however,  because 
just for fun I took out that call and it was much faster.   

I generated 100 million random numbers in a for loop with and extra test 
to print out the last 10 numbers and here are the times:


  CMWC4096  =  0.712  seconds
   KESSEL  =  4.504  seconds


Here is the loop I used

for (i=1; i0; i--) {
   cur = CMWC4096();
   if (i = 10) {
 printf(%20u %20d\n, cur, (int) cur - last);
   }
   last = cur;
 }


And the code for CMWC4096 (without the initialization code)

static unsigned long Q[4096], c=362436;


unsigned int CMWC4096(void)
{
 unsigned long long t, a=18782LL, b=4294967295LL;
 static int i=4095;
 unsigned int x, r=b-1;
 i=(i+1)4095;
 t=a*Q[i]+c;
 c=(t32);
 t=(tb)+c;
 if(tr) {c++; t=t-b;}
 return(Q[i]=r-t);
}





A van Kessel wrote:

A reasonable xor+shift random (similar to Marsaglia's, but only 64bit
instead of 128 bits), using the pentium's rdtsc-instrunction to add
additional entropy (i used gnu's inline assembler) :::

#define rdtscll(val) \
  __asm__ __volatile__(rdtsc : =A (val))

typedef unsigned long long BIGTHING;
BIGTHING rdtsc_rand(void);

/**/
BIGTHING rdtsc_rand(void)
{
static BIGTHING val=0xULL;
BIGTHING new;

rdtscll(new);
val ^= (val  15) ^ (val  14) ^ 9 ^ new;

return val;
}
/**/

The extra ^9 at the end can be omitted if the new is nonzero.
(is only meant to avoid the val becoming all-zeros. And shifting zeros won't
change the value ;-)

HTH,
AvK
___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/

  

___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/


Re: [computer-go] Random

2008-05-20 Thread Don Dailey
I doesn't seem too fast based on my test, but perhaps there are ways to 
optimize it.


I would like to mention that your generator is 64 bit and the other 
generator was 32 bits but I'm running on a 64 bit core 2 duo OS and do 
not know how much of a factor this is or isn't.


If RDTSC actually is too slow,  a way around it is to design the RDTSC 
to be called only occasionally.  But this involves a branching 
instruction which is probably going to hurt it too. 

I wonder if you could have a burst version that generates several at a 
time and queues them up?   Then you grab them off the queue until you 
run out, then you insert some entropy with RDTSC and generate 16 more 
numbers or something like that.This still requires a branch 
instruction. Of course you are inserting far less entropy into the 
system if you only do it occasionally,  but I would bet that you have 
several bits of entropy in this case,  because a lot is going on before 
you get to the next call. 


- Don



A van Kessel wrote:
The question I have is how much does RDTSC slow this down?I may do 


I don't know.
If I understand correctly, rdtsc can be executed in parallen with *some*
other instructions (and places no barrier in the code), in which case
it could be executed at no additional cost (except the instruction fetching,
of course)
I have not yet been able to instruct GCC to use the mmx or sse3 instructions/
registers to do the shifting. Code could be reshuffeled to allow the
compiler more freedom.

AvK
___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/

  

___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/


Re: [computer-go] Random

2008-05-20 Thread A van Kessel
 I would like to mention that your generator is 64 bit and the other 
That is correct.

My timings (Haven't profiled yet):
WITH TSC:
real0m0.902s
user0m0.870s
sys 0m0.002s

WITHOUT:
real0m0.613s
user0m0.582s
sys 0m0.000s

That's for 100 M random numbers.

And inlining would probably help a lot, too.

AvK
___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/


Re: [computer-go] Random

2008-05-20 Thread Don Dailey
That's way different that what I'm getting.   Something is wrong here. 


I'm getting 4.08 with RDTSC and when I just set new  to 0ull  I get 0.696

One of us must have done something wrong. 


- Don


A van Kessel wrote:
I would like to mention that your generator is 64 bit and the other 


That is correct.

My timings (Haven't profiled yet):
WITH TSC:
real0m0.902s
user0m0.870s
sys 0m0.002s

WITHOUT:
real0m0.613s
user0m0.582s
sys 0m0.000s

That's for 100 M random numbers.

And inlining would probably help a lot, too.

AvK
___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/

  

___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/


Re: [computer-go] Random

2008-05-20 Thread Don Dailey

#include stdio.h
#include stdlib.h
I'm including my code below.   Also, here are my reported times:

Without RDTSC

real0m1.008s
user0m0.668s
sys 0m0.004s


With RDTSC

real0m5.790s
user0m3.956s
sys 0m0.016s


To turn on or off RDTSC  see the rdtsc_rand line that says, if (1)

- Don

--[ snip ]


#define rdtscll(val) \
 __asm__ __volatile__(rdtsc : =A (val))


unsigned long long rdtsc_rand(void);

/**/
unsigned long long rdtsc_rand(void)
{
 static unsigned long long val=0xULL;
 unsigned long long new = 0llu;

 if (1) {
   rdtscll(new);
 }

 val ^= (val  15) ^ (val  14) ^ 9 ^ new;

 return val;
}


void kessel()
{
 int i;
 unsigned long long  last = 0;
 unsigned long long  cur = 0;

 for (i=1; i0; i--) {
   cur = rdtsc_rand();
   if (i = 10) {
 printf(%20llu %20lld\n, cur, (int) cur - last);
   }
   last = cur;
 }
}



int main(int argc, char **argv)
{

 kessel();

 return(0);
}


A van Kessel wrote:
I would like to mention that your generator is 64 bit and the other 


That is correct.

My timings (Haven't profiled yet):
WITH TSC:
real0m0.902s
user0m0.870s
sys 0m0.002s

WITHOUT:
real0m0.613s
user0m0.582s
sys 0m0.000s

That's for 100 M random numbers.

And inlining would probably help a lot, too.

AvK
___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/

  

___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/


Re: [computer-go] Random

2008-05-20 Thread A van Kessel
I Just omitted the new variable:

/**/
BIGTHING rdtsc_rand(void)
{
static BIGTHING val=0xULL;

#if WANT_RDTSC
BIGTHING new;
rdtscll(new);
val ^= (val  15) ^ (val  14) ^ new;
#else
val ^= (val  15) ^ (val  14) ^ 9 ;
#endif

return val;
}
/**/

AvK
___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/


Re: [computer-go] Random

2008-05-20 Thread A van Kessel
  Has anyone looked at the resultant distributions, to
Well, mine was pretty random.
Maybe a bit too random.
Changing the 14 and 15 shifts effectively cripples it.

I have not looked at sequential correlation, only at the
distribution, by binning the values into a histogram.
As far as I could see it has a good spreading. YMMV.

AvK
___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/


Re: [computer-go] Random

2008-05-20 Thread Don Dailey



terry mcintyre wrote:

Has anyone looked at the resultant distributions, to
determine how random they are?
  
They should be run against the dieharder tests before any confidence is 
placed in them. But I did look at them visually to see if there was 
anything wrong that was immediately obvious to me. Visual inspection may 
find an obvious bug, but it's not worth much after that.


If I could get van Kessel's numbers I would consider packaging it up and 
running it through the diharder tests, but otherwise I see no reason 
since I am not yet happy with the performance.


- Don




--- Don Dailey [EMAIL PROTECTED] wrote:

  

#include stdio.h
#include stdlib.h
I'm including my code below.   Also, here are my
reported times:

Without RDTSC

real0m1.008s
user0m0.668s
sys 0m0.004s


With RDTSC

real0m5.790s
user0m3.956s
sys 0m0.016s


To turn on or off RDTSC  see the rdtsc_rand line
that says, if (1)

- Don

--[ snip ]


#define rdtscll(val) \
  __asm__ __volatile__(rdtsc : =A (val))


unsigned long long rdtsc_rand(void);




/**/
  

unsigned long long rdtsc_rand(void)
{
  static unsigned long long
val=0xULL;
  unsigned long long new = 0llu;

  if (1) {
rdtscll(new);
  }

  val ^= (val  15) ^ (val  14) ^ 9 ^ new;
 
  return val;

}


void kessel()
{
  int i;
  unsigned long long  last = 0;
  unsigned long long  cur = 0;

  for (i=1; i0; i--) {
cur = rdtsc_rand();
if (i = 10) {
  printf(%20llu %20lld\n, cur, (int) cur -
last);
}
last = cur;
  }
}



int main(int argc, char **argv)
{

  kessel();

  return(0);
}


A van Kessel wrote:


I would like to mention that your generator is 64

bit and the other 




That is correct.

My timings (Haven't profiled yet):
WITH TSC:
real0m0.902s
user0m0.870s
sys 0m0.002s

WITHOUT:
real0m0.613s
user0m0.582s
sys 0m0.000s

That's for 100 M random numbers.

And inlining would probably help a lot, too.

AvK
___
computer-go mailing list
computer-go@computer-go.org

  

http://www.computer-go.org/mailman/listinfo/computer-go/
  
  
  

___
computer-go mailing list
computer-go@computer-go.org



http://www.computer-go.org/mailman/listinfo/computer-go/
  



Terry McIntyre lt;[EMAIL PROTECTED]gt;

“Wherever is found what is called a paternal government, there is found state 
education. It has been discovered that the best way to insure implicit 
obedience is to commence tyranny in the nursery.”

Benjamin Disraeli, Speech in the House of Commons [June 15, 1874]


  
___

computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/

  

___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/


Re: [computer-go] Random

2008-05-20 Thread Don Dailey
Ok,  please check your number again.I set mine up like yours just in 
case and I still get at least a 5x slowdown.


I think yours are probably wrong because I have seen numbers that 
indicate RDTSC is really slow.


- Don



A van Kessel wrote:

I Just omitted the new variable:

/**/
BIGTHING rdtsc_rand(void)
{
static BIGTHING val=0xULL;

#if WANT_RDTSC
BIGTHING new;
rdtscll(new);
val ^= (val  15) ^ (val  14) ^ new;
#else
val ^= (val  15) ^ (val  14) ^ 9 ;
#endif

return val;
}
/**/

AvK
___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/

  

___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/


Re: [computer-go] Random

2008-05-20 Thread terry mcintyre
Are you using the same hardware? I was looking over
the instruction timings, and there's a lot of
variation depending on the architecture.

--- Don Dailey [EMAIL PROTECTED] wrote:

 That's way different that what I'm getting.  
 Something is wrong here. 
 
 I'm getting 4.08 with RDTSC and when I just set new 
 to 0ull  I get 0.696
 
 One of us must have done something wrong. 
 
 - Don
 
 
 A van Kessel wrote:
  I would like to mention that your generator is 64
 bit and the other 
  
  That is correct.
 
  My timings (Haven't profiled yet):
  WITH TSC:
  real0m0.902s
  user0m0.870s
  sys 0m0.002s
 
  WITHOUT:
  real0m0.613s
  user0m0.582s
  sys 0m0.000s
 
  That's for 100 M random numbers.
 
  And inlining would probably help a lot, too.
 
  AvK
  ___
  computer-go mailing list
  computer-go@computer-go.org
 

http://www.computer-go.org/mailman/listinfo/computer-go/
 

 ___
 computer-go mailing list
 computer-go@computer-go.org

http://www.computer-go.org/mailman/listinfo/computer-go/
 


Terry McIntyre lt;[EMAIL PROTECTED]gt;

“Wherever is found what is called a paternal government, there is found state 
education. It has been discovered that the best way to insure implicit 
obedience is to commence tyranny in the nursery.”

Benjamin Disraeli, Speech in the House of Commons [June 15, 1874]


  
___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/


Re: [computer-go] Random

2008-05-20 Thread A van Kessel
Measurements ar pretty consistent.

Hardware:
Linux localhost.localdomain 2.6.23.1-42.fc8 #1 SMP Tue Oct 30 13:55:12 EDT 2007 
i686 athlon i386 GNU/Linux

(I didnot even know it was an athlon !)

AvK
___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/


Re: [computer-go] Random

2008-05-20 Thread A van Kessel
Mine:
cat /proc/cpuinfo 
processor   : 0
vendor_id   : AuthenticAMD
cpu family  : 6
model   : 10
model name  : AMD Athlon(tm) XP 2800+
stepping: 0
cpu MHz : 2079.595
cache size  : 512 KB
fdiv_bug: no
hlt_bug : no
f00f_bug: no
coma_bug: no
fpu : yes
fpu_exception   : yes
cpuid level : 1
wp  : yes
flags   : fpu vme de pse tsc msr pae mce cx8 apic mtrr pge mca cmov pat 
pse36 mmx fxsr sse syscall mmxext 3dnowext 3dnow up ts
bogomips: 4160.98
clflush size: 32

AvK
___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/


Re: [computer-go] Random

2008-05-16 Thread Don Dailey



Michael Williams wrote:
I don't think Don was saying to use many calls to RDTSC to generate a 
single random number.

I think he meant do something like (FastBadRand() XOR RDTSC).
The first part has low quality low-order bits and the second part has 
low quality high-order bits.
That was my exact idea,  to xor or add RDTSC to the results.If that 
really is a slow operation then it basically kills the idea.   The cycle 
time should be published somewhere though.


- Don




Also, I can't imagine why executing a RDTSC would take 50 cycles.  But 
I couldn't find any docs on that aspect of the instruction.




steve uurtamo wrote:

the only thing to watch is that you'll likely need
30+ bits from these guys to seed a prng, and
getting those bits in any organized way is likely
going to happen on a regular schedule (i.e. if
you get them in a loop, you're likely going to
space them out in an organized way).

s.


On 5/15/08, Don Dailey [EMAIL PROTECTED] wrote:
For a long time I have pondered whether you could build a very high 
quality

random number generator that was extremely fast using the pentium RDTSC
instruction as a low order bit entropy source. The idea would be 
to use
an extremely fast (but low quality) pseudo random number generator,  
but
modify the output (or the internal state of the generator) with the 
time

stamp register at each call.

RDTSC reads the pentiums internal clock and is basically just a 64 bit
counter.However it increments very quickly and could be viewed 
as an
entropy source in the lowest bits as it would introduce at least a 
little

bit of non-determinism, and I think a little is all you would need to
transform a horrible generator into a good practical one for many
applications.   I  think the lowest 2 or 3 (or more)  bits would 
appear to
modern processors as almost unpredictable since there is so much 
going on

inside modern computers that are unpredictable.
I don't know if the call to RDTSC is fast or how it would affect the
parallelism of todays modern machines.   I'm not particularly 
interested in
non-deterministic generators as I sometimes depend on this for 
testing and

debugging,  but it's an idea I thought I would throw out there.
- Don





Don Dailey wrote:
If you are looking for a cheap fast and simple random number 
generator,  A
post by George Marsaglia, an expert/guru on random number generation 
has

several and a C implemention.
These are one line generators,  coded as macros.He also 
discusses the

period and quality of each of them. This is a gem of a post  on
sci.stat.math,sci.math  if you are interested in RNG:

  http://www.math.niu.edu/~rusin/known-math/99/RNG

- Don



Heikki Levanto wrote:


In addition, xor_shift is better than builtin rand() and faster and
much smaller than MT.

I don't know that much about random numbers, so excuse my 
ignorance. But

a

bit of googling got me to the Park - Miller Minimal Standard random

number

generator

http://www.firstpr.com.au/dsp/rand31/p1192-park.pdf
From what I read, it should be quite sufficient for go programs. 
It is

dead simple and fast:

long int pmrand() {
   const long int a=16807;
   const long int m= ( 1  31 ) -1;
   pmrandseed = ( pmrandseed * a ) % m ;
   return pmrandseed;
} /* pmrand */


Should I worry about this not being good enough?
 - Heikki






___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/



___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/


___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/



___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/


___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/


Re: [computer-go] Random

2008-05-16 Thread Don Dailey



Michael Williams wrote:
I don't think Don was saying to use many calls to RDTSC to generate a 
single random number.

I think he meant do something like (FastBadRand() XOR RDTSC).
The first part has low quality low-order bits and the second part has 
low quality high-order bits.


I also intended for RDTSC to change the state of the random number 
generator which would be extremely chaotic over time.   Some 
FastBadRand() generators use the last value returned as the state.


- Don



Also, I can't imagine why executing a RDTSC would take 50 cycles.  But 
I couldn't find any docs on that aspect of the instruction.




steve uurtamo wrote:

the only thing to watch is that you'll likely need
30+ bits from these guys to seed a prng, and
getting those bits in any organized way is likely
going to happen on a regular schedule (i.e. if
you get them in a loop, you're likely going to
space them out in an organized way).

s.


On 5/15/08, Don Dailey [EMAIL PROTECTED] wrote:
For a long time I have pondered whether you could build a very high 
quality

random number generator that was extremely fast using the pentium RDTSC
instruction as a low order bit entropy source. The idea would be 
to use
an extremely fast (but low quality) pseudo random number generator,  
but
modify the output (or the internal state of the generator) with the 
time

stamp register at each call.

RDTSC reads the pentiums internal clock and is basically just a 64 bit
counter.However it increments very quickly and could be viewed 
as an
entropy source in the lowest bits as it would introduce at least a 
little

bit of non-determinism, and I think a little is all you would need to
transform a horrible generator into a good practical one for many
applications.   I  think the lowest 2 or 3 (or more)  bits would 
appear to
modern processors as almost unpredictable since there is so much 
going on

inside modern computers that are unpredictable.
I don't know if the call to RDTSC is fast or how it would affect the
parallelism of todays modern machines.   I'm not particularly 
interested in
non-deterministic generators as I sometimes depend on this for 
testing and

debugging,  but it's an idea I thought I would throw out there.
- Don





Don Dailey wrote:
If you are looking for a cheap fast and simple random number 
generator,  A
post by George Marsaglia, an expert/guru on random number generation 
has

several and a C implemention.
These are one line generators,  coded as macros.He also 
discusses the

period and quality of each of them. This is a gem of a post  on
sci.stat.math,sci.math  if you are interested in RNG:

  http://www.math.niu.edu/~rusin/known-math/99/RNG

- Don



Heikki Levanto wrote:


In addition, xor_shift is better than builtin rand() and faster and
much smaller than MT.

I don't know that much about random numbers, so excuse my 
ignorance. But

a

bit of googling got me to the Park - Miller Minimal Standard random

number

generator

http://www.firstpr.com.au/dsp/rand31/p1192-park.pdf
From what I read, it should be quite sufficient for go programs. 
It is

dead simple and fast:

long int pmrand() {
   const long int a=16807;
   const long int m= ( 1  31 ) -1;
   pmrandseed = ( pmrandseed * a ) % m ;
   return pmrandseed;
} /* pmrand */


Should I worry about this not being good enough?
 - Heikki






___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/



___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/


___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/



___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/


___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/


Re: [computer-go] Random

2008-05-16 Thread terry mcintyre
Regarding the time used by RDTSC:

From
http://smallcode.weblogs.us/2007/12/07/performance-measurements-with-rdtsc/

Intel and Agner Fog recommend measuring the overhead
of RDTSC function and subtracting it from your result.
The overhead is relatively low (150-200 clock cycles)
and it occurs in all tested functions, so you can
neglect it when measuring long functions (e.g., 100
000 clock cycles).

NOTE: the page above recommends flushing the cache
before  calling RDTSC, when using it for timing
purposes. There is probably no need to do so when
grabbing LSBs.

I wonder, however, if the LSBs would be as random as
all that, when called frequently in
quasi-deterministic code which takes a predictable
number of cycles between invocations.



Terry McIntyre lt;[EMAIL PROTECTED]gt;

“Wherever is found what is called a paternal government, there is found state 
education. It has been discovered that the best way to insure implicit 
obedience is to commence tyranny in the nursery.”

Benjamin Disraeli, Speech in the House of Commons [June 15, 1874]


  
___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/


Re: [computer-go] Random

2008-05-16 Thread Don Dailey



terry mcintyre wrote:

Regarding the time used by RDTSC:

From
http://smallcode.weblogs.us/2007/12/07/performance-measurements-with-rdtsc/

Intel and Agner Fog recommend measuring the overhead
of RDTSC function and subtracting it from your result.
The overhead is relatively low (150-200 clock cycles)
and it occurs in all tested functions, so you can
neglect it when measuring long functions (e.g., 100
000 clock cycles).

NOTE: the page above recommends flushing the cache
before  calling RDTSC, when using it for timing
purposes. There is probably no need to do so when
grabbing LSBs.

I wonder, however, if the LSBs would be as random as
all that, when called frequently in
quasi-deterministic code which takes a predictable
number of cycles between invocations.
  
I'm not interested in using it here to measure performance, but as a 
possible way to have a very fast and very high quality random number 
function. But this won't happen if RDTSC isn't fast and it doesn't 
appear to be very fast.


I don't expect RDTSC to be very random either, I'm more interested in 
the chaos it presents to the random number system which is produced even 
with very little agitation added to the system. Even an occasional 1 bit 
change would cure many of the problems of some fast random number 
generators.


If you were to call this random number generator consecutively, many 
time in a tight loop, I suspect that you will get a LOT of variation in 
the number of cycles that have passed between calls, certainly enough to 
make it completely unpredictable in the long run. Like weather 
predictions you might predict the next day (or call) with some level of 
reasonable accuracy but not a specific day in the next month.


Every deterministic pseudo random number generator in existence always 
has some kind of structure. The main difference between what we consider 
good and bad ones is how well that structure is obfuscated or hidden 
from view. We try to be clever so that statistical tests cannot see the 
structure. One of primary methods to hide this structure is to make it 
so big (by long cycle lengths) that we can only see a tiny portion of 
it. For instance if every zillion'th bit alternated between 0 and 1, it 
would be hard to observe.


So if you can add a small amount of non-determinism you can probably 
bust up the hidden structure.


At any rate, it seems like it's not workable as a fast alternative to 
RNG. It might be combined with a slow very high quality generator to 
produce numbers that are somewhat closer to true random numbers.


- Don





Terry McIntyre lt;[EMAIL PROTECTED]gt;

“Wherever is found what is called a paternal government, there is found state 
education. It has been discovered that the best way to insure implicit 
obedience is to commence tyranny in the nursery.”

Benjamin Disraeli, Speech in the House of Commons [June 15, 1874]


  
___

computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/

  

___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/


Re: [computer-go] Random

2008-05-16 Thread Don Dailey



Zach Wegner wrote:

What you could do is XOR the RDTSC into the seed (or array or whatever
your RNG uses) at the beginning of each playout. That adds to the
chaos but doesn't slow it down much at all.
  
I like your idea.   Yes, you could probably use a really fast simple RNG 
and do this. AnchorMan had a very trivial RNG and I noticed that if 
you played enough games, you start getting the same games over and 
over.   So I could only play a few hundreds before this started 
happening (for instance playing anchor vs anchor.) It seems like 
with 4 billion possible seeds that this would not happen (each games 
started with a seed based on the time()  call.)  But apparently 
something was going on that I didn't understand because there seemed to 
be only a few hundred games possible (at any fixed level.)  

I switched over to Mersenne Twister and this problem went away.  MT did 
not improve the playing quality in any way I could notice, so I don't  
believe MC in general requires a very good RNG. 

I once built a card playing program, and while developing a playing 
strategy I tested different versions against each other.  But then I 
tried as a sanity check, testing the same version against itself,  and I 
noticed a systematic bias,  one particular side was winning something 
like 53 or 54 percent of the games even though the conditions were 
unbiased.   I discovered the problem was with the RNG in the C library 
(this was a long time ago.)I solved the problem by changing the way 
I shuffled the cards.Originally I created a deck from scratch which 
always had the same ordering, then I would apply the standard 
Fischer-Yates shuffle. The fix was to reuse the deck from the last 
game and shuffle THAT deck.   Basically I grabbed up all the cards in 
the players hands and on the table and put them back in the deck just 
like us humans do when playing cards, then I would shuffle them.The 
effect was that I implicitly created a more sophisticated RNG with lots 
of state and more than likely a very long cycle time compared to the 
simple one I started with.


This could be done with your go program too.   If you have some sort of 
list of all the legal points at the beginning of the game that you work 
with and manipulate,   just leave it alone instead of reinitializing 
it.Or let the move sequences of the previous game impact the initial 
ordering or how the game is played.You would be getting a more 
sophisticated RNG for free.   Of course you have to save state between 
program invocations and that's probably too ugly.  


- Don




___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/

  

___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/


Re: [computer-go] Random

2008-05-16 Thread David Doshay

Hi,

As mentioned before, Monte Carlo simulations in physics was my thesis
topic, and there we need REALLY good PRNGs or we see the effect in
the results.

There is always a tradeoff between fast and good. If the newer Mersine
Twister algorithms (which are very good) is too slow and you want to
test an alternative, you can use the trick that is in Knuth that I  
used for
my thesis work. It is a 2 step generator that shuffles. You build an  
array
that holds a set of PRNGs straight from your crude but very fast  
generator
(I was partial to a list of 273), Your first PRNG call mod(arraysize)  
picks

the PRN you will use, and then the second refills that spot.

No promises that this is any faster, but for lattice simulations where
any correlations pop right out at you sort of like a herringbone  
pattern,

this shuffling worked great for me.

Personally, I think that much of the really high quality issues are  
not

that important for MC Go right now. I think that other things like not
having a reasonable distribution function (which UCT does a remarkable
job of smoothing over) completely overwhelm the effects of a poor PRNG.

Cheers,
David



On 16, May 2008, at 10:42 AM, Don Dailey wrote:




terry mcintyre wrote:

Regarding the time used by RDTSC:

From
http://smallcode.weblogs.us/2007/12/07/performance-measurements-with-rdtsc/

Intel and Agner Fog recommend measuring the overhead
of RDTSC function and subtracting it from your result.
The overhead is relatively low (150-200 clock cycles)
and it occurs in all tested functions, so you can
neglect it when measuring long functions (e.g., 100
000 clock cycles).

NOTE: the page above recommends flushing the cache
before  calling RDTSC, when using it for timing
purposes. There is probably no need to do so when
grabbing LSBs.

I wonder, however, if the LSBs would be as random as
all that, when called frequently in
quasi-deterministic code which takes a predictable
number of cycles between invocations.

I'm not interested in using it here to measure performance, but as a  
possible way to have a very fast and very high quality random number  
function. But this won't happen if RDTSC isn't fast and it doesn't  
appear to be very fast.


I don't expect RDTSC to be very random either, I'm more interested  
in the chaos it presents to the random number system which is  
produced even with very little agitation added to the system. Even  
an occasional 1 bit change would cure many of the problems of some  
fast random number generators.


If you were to call this random number generator consecutively, many  
time in a tight loop, I suspect that you will get a LOT of variation  
in the number of cycles that have passed between calls, certainly  
enough to make it completely unpredictable in the long run. Like  
weather predictions you might predict the next day (or call) with  
some level of reasonable accuracy but not a specific day in the next  
month.


Every deterministic pseudo random number generator in existence  
always has some kind of structure. The main difference between what  
we consider good and bad ones is how well that structure is  
obfuscated or hidden from view. We try to be clever so that  
statistical tests cannot see the structure. One of primary methods  
to hide this structure is to make it so big (by long cycle  
lengths) that we can only see a tiny portion of it. For instance if  
every zillion'th bit alternated between 0 and 1, it would be hard to  
observe.


So if you can add a small amount of non-determinism you can probably  
bust up the hidden structure.


At any rate, it seems like it's not workable as a fast alternative  
to RNG. It might be combined with a slow very high quality generator  
to produce numbers that are somewhat closer to true random numbers.


- Don





Terry McIntyre lt;[EMAIL PROTECTED]gt;

“Wherever is found what is called a paternal government, there is  
found state education. It has been discovered that the best way to  
insure implicit obedience is to commence tyranny in the nursery.”


Benjamin Disraeli, Speech in the House of Commons [June 15, 1874]


 ___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/



___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/


___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/


Re: [computer-go] Random

2008-05-16 Thread Olivier Teytaud

Personally, I think that much of the really high quality issues are not
that important for MC Go right now. I think that other things like not
having a reasonable distribution function (which UCT does a remarkable
job of smoothing over) completely overwhelm the effects of a poor PRNG.


I agree with that.

By the way,
I have spent time on the use of improved forms of Monte-Carlo 
(quasi-random, stratification, ...) but I've never found an efficient 
trick.


OT
___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/


Re: [computer-go] Random

2008-05-16 Thread Don Dailey
That's very interesting and I believe it explains everything perfectly. 
If I understand this correctly, my 4 billion possible seeds (I used a 32 
bit seed) cannot produce 32 billion different games (against the same 
deterministic opponent.) In my implementation there were also issues 
with the lower ordered bits which of course are less random.


- Don



terry mcintyre wrote:
An interesting note from 
http://en.wikipedia.org/wiki/Knuth_shuffle which

appears to be pertinent to Don's remarks about a
limited number of games: 


quote
Limited PRNG state space

An additional problem occurs when the Fisher-Yates
shuffle is used with a pseudorandom number generator:
as the sequence of numbers output by such a generator
is entirely determined by its internal state at the
start of a sequence, a shuffle driven by such a
generator cannot possibly produce more distinct
permutations than the generator has distinct possible
states. Even when the number of possible states
exceeds the number of permutations, the irregular
nature of the mapping from sequences of numbers to
permutations means that some permutations will occur
more often than others. Thus, to minimize bias, the
number of states of the PRNG should exceed the number
of permutations by at least several orders of
magnitude.

For example, the built-in pseudorandom number
generator provided by many programming languages
and/or libraries may often have only 32 bits of
internal state, which means it can only produce 232
different sequences of numbers. If such a generator is
used to shuffle a deck of 52 playing cards, it can
only ever produce a vanishingly small fraction of the
52! #8776; 2225.6 possible permutations. Thus, it's
impossible for a generator with less than 226 bits of
internal state to produce all the possible
permutations of a 52-card deck, and for a (reasonably)
unbiased shuffle, the generator must have at least
about 250 bits of state.

A further problem occurs when a simple linear
congruential PRNG is used with the
divide-and-take-remainder method of range reduction
described above. The problem here is that the
low-order bits of a linear congruential PRNG are less
random than the high-order ones: the low n bits of the
generator themselves have a period of at most 2n. When
the divisor is a power of two, taking the remainder
essentially means throwing away the high-order bits,
such that one ends up with a significantly less random
value.

Also, of course, no pseudorandom number generator can
produce more distinct sequences than there are
distinct seed values it may be initialized with. Thus,
it doesn't matter much if a generator has 1024 bits of
internal state if it is only ever initialized with a
32-bit seed.
/quote

The page also describes several other sources of bias
which may be pertinent to the development of MC
programs.


Terry McIntyre lt;[EMAIL PROTECTED]gt;

“Wherever is found what is called a paternal government, there is found state 
education. It has been discovered that the best way to insure implicit 
obedience is to commence tyranny in the nursery.”

Benjamin Disraeli, Speech in the House of Commons [June 15, 1874]


  
___

computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/

  

___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/


Re: [computer-go] Random

2008-05-16 Thread David Doshay
These shuffles are different than the one I used and attempted to  
describe.


Cheers,
David



On 16, May 2008, at 12:55 PM, terry mcintyre wrote:


An interesting note from
http://en.wikipedia.org/wiki/Knuth_shuffle which
appears to be pertinent to Don's remarks about a
limited number of games:

quote
Limited PRNG state space


___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/


Re: [computer-go] Random

2008-05-15 Thread Don Dailey
If you are looking for a cheap fast and simple random number generator,  
A post by George Marsaglia, an expert/guru on random number generation 
has several and a C implemention.


These are one line generators,  coded as macros.He also discusses 
the period and quality of each of them.  

This is a gem of a post  on sci.stat.math,sci.math  if you are 
interested in RNG:


   http://www.math.niu.edu/~rusin/known-math/99/RNG

- Don



Heikki Levanto wrote:

In addition, xor_shift is better than builtin rand() and faster and
much smaller than MT.  



I don't know that much about random numbers, so excuse my ignorance. But a
bit of googling got me to the Park - Miller Minimal Standard random number
generator 
   http://www.firstpr.com.au/dsp/rand31/p1192-park.pdf


From what I read, it should be quite sufficient for go programs. It is
dead simple and fast:

long int pmrand() {
const long int a=16807;
const long int m= ( 1  31 ) -1;
pmrandseed = ( pmrandseed * a ) % m ;
return pmrandseed;
} /* pmrand */


Should I worry about this not being good enough? 


  - Heikki



  

___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/


Re: [computer-go] Random

2008-05-15 Thread Don Dailey
For a long time I have pondered whether you could build a very high 
quality random number generator that was extremely fast using the 
pentium RDTSC instruction as a low order bit entropy source. The 
idea would be to use an extremely fast (but low quality) pseudo random 
number generator,  but modify the output (or the internal state of the 
generator) with the time stamp register at each call.


RDTSC reads the pentiums internal clock and is basically just a 64 bit 
counter.However it increments very quickly and could be viewed as an 
entropy source in the lowest bits as it would introduce at least a 
little bit of non-determinism, and I think a little is all you would 
need to transform a horrible generator into a good practical one for 
many applications.   I  think the lowest 2 or 3 (or more)  bits would 
appear to modern processors as almost unpredictable since there is so 
much going on inside modern computers that are unpredictable. 

I don't know if the call to RDTSC is fast or how it would affect the 
parallelism of todays modern machines.   I'm not particularly interested 
in non-deterministic generators as I sometimes depend on this for 
testing and debugging,  but it's an idea I thought I would throw out 
there. 


- Don




Don Dailey wrote:
If you are looking for a cheap fast and simple random number 
generator,  A post by George Marsaglia, an expert/guru on random 
number generation has several and a C implemention.


These are one line generators,  coded as macros.He also discusses 
the period and quality of each of them. 
This is a gem of a post  on sci.stat.math,sci.math  if you are 
interested in RNG:


   http://www.math.niu.edu/~rusin/known-math/99/RNG

- Don



Heikki Levanto wrote:

In addition, xor_shift is better than builtin rand() and faster and
much smaller than MT.  


I don't know that much about random numbers, so excuse my ignorance. 
But a
bit of googling got me to the Park - Miller Minimal Standard random 
number

generatorhttp://www.firstpr.com.au/dsp/rand31/p1192-park.pdf

From what I read, it should be quite sufficient for go programs. It is
dead simple and fast:

long int pmrand() {
const long int a=16807;
const long int m= ( 1  31 ) -1;
pmrandseed = ( pmrandseed * a ) % m ;
return pmrandseed;
} /* pmrand */


Should I worry about this not being good enough?
  - Heikki



  

___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/


___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/


Re: [computer-go] Random

2008-05-15 Thread Don Dailey



Heikki Levanto wrote:

In addition, xor_shift is better than builtin rand() and faster and
much smaller than MT.  



I don't know that much about random numbers, so excuse my ignorance. But a
bit of googling got me to the Park - Miller Minimal Standard random number
generator 
   http://www.firstpr.com.au/dsp/rand31/p1192-park.pdf
  
That reference goes back to 1988 and what it comes to random number 
generators that is ancient.Is there a modern analysis of this 
generator anywhere?


- Don




From what I read, it should be quite sufficient for go programs. It is
dead simple and fast:

long int pmrand() {
const long int a=16807;
const long int m= ( 1  31 ) -1;
pmrandseed = ( pmrandseed * a ) % m ;
return pmrandseed;
} /* pmrand */


Should I worry about this not being good enough? 


  - Heikki



  

___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/


Re: [computer-go] Random

2008-05-15 Thread steve uurtamo
the only thing to watch is that you'll likely need
30+ bits from these guys to seed a prng, and
getting those bits in any organized way is likely
going to happen on a regular schedule (i.e. if
you get them in a loop, you're likely going to
space them out in an organized way).

s.


On 5/15/08, Don Dailey [EMAIL PROTECTED] wrote:
 For a long time I have pondered whether you could build a very high quality
 random number generator that was extremely fast using the pentium RDTSC
 instruction as a low order bit entropy source. The idea would be to use
 an extremely fast (but low quality) pseudo random number generator,  but
 modify the output (or the internal state of the generator) with the time
 stamp register at each call.

 RDTSC reads the pentiums internal clock and is basically just a 64 bit
 counter.However it increments very quickly and could be viewed as an
 entropy source in the lowest bits as it would introduce at least a little
 bit of non-determinism, and I think a little is all you would need to
 transform a horrible generator into a good practical one for many
 applications.   I  think the lowest 2 or 3 (or more)  bits would appear to
 modern processors as almost unpredictable since there is so much going on
 inside modern computers that are unpredictable.
 I don't know if the call to RDTSC is fast or how it would affect the
 parallelism of todays modern machines.   I'm not particularly interested in
 non-deterministic generators as I sometimes depend on this for testing and
 debugging,  but it's an idea I thought I would throw out there.
 - Don





 Don Dailey wrote:
  If you are looking for a cheap fast and simple random number generator,  A
 post by George Marsaglia, an expert/guru on random number generation has
 several and a C implemention.
 
  These are one line generators,  coded as macros.He also discusses the
 period and quality of each of them. This is a gem of a post  on
 sci.stat.math,sci.math  if you are interested in RNG:
 
http://www.math.niu.edu/~rusin/known-math/99/RNG
 
  - Don
 
 
 
  Heikki Levanto wrote:
 
  
In addition, xor_shift is better than builtin rand() and faster and
much smaller than MT.
   
  
   I don't know that much about random numbers, so excuse my ignorance. But
 a
   bit of googling got me to the Park - Miller Minimal Standard random
 number
   generator
 http://www.firstpr.com.au/dsp/rand31/p1192-park.pdf
  
   From what I read, it should be quite sufficient for go programs. It is
   dead simple and fast:
  
   long int pmrand() {
  const long int a=16807;
  const long int m= ( 1  31 ) -1;
  pmrandseed = ( pmrandseed * a ) % m ;
  return pmrandseed;
   } /* pmrand */
  
  
   Should I worry about this not being good enough?
- Heikki
  
  
  
  
  
  ___
  computer-go mailing list
  computer-go@computer-go.org
  http://www.computer-go.org/mailman/listinfo/computer-go/
 
 
 ___
 computer-go mailing list
 computer-go@computer-go.org
 http://www.computer-go.org/mailman/listinfo/computer-go/

___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/


Re: [computer-go] Random

2008-05-15 Thread Zach Wegner
IIRC the RDTSC instruction is very slow, on the order of 50 cycles. In
addition, I like having deterministic generators so that
hypothetically I could reproduce any result.

In my chess program I use a modified version of Agner Fog's Ranrot.
It's very fast and very random. There's a paper on his site on the
theory behind it:
http://www.agner.org/random/theory/ (the first link).

You can see the actual generator I use here:
http://zct.cvs.sourceforge.net/*checkout*/zct/zct/rand.c?revision=1.2
___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/


Re: [computer-go] Random

2008-05-15 Thread Michael Williams

I don't think Don was saying to use many calls to RDTSC to generate a single 
random number.
I think he meant do something like (FastBadRand() XOR RDTSC).
The first part has low quality low-order bits and the second part has low 
quality high-order bits.

Also, I can't imagine why executing a RDTSC would take 50 cycles.  But I 
couldn't find any docs on that aspect of the instruction.



steve uurtamo wrote:

the only thing to watch is that you'll likely need
30+ bits from these guys to seed a prng, and
getting those bits in any organized way is likely
going to happen on a regular schedule (i.e. if
you get them in a loop, you're likely going to
space them out in an organized way).

s.


On 5/15/08, Don Dailey [EMAIL PROTECTED] wrote:

For a long time I have pondered whether you could build a very high quality
random number generator that was extremely fast using the pentium RDTSC
instruction as a low order bit entropy source. The idea would be to use
an extremely fast (but low quality) pseudo random number generator,  but
modify the output (or the internal state of the generator) with the time
stamp register at each call.

RDTSC reads the pentiums internal clock and is basically just a 64 bit
counter.However it increments very quickly and could be viewed as an
entropy source in the lowest bits as it would introduce at least a little
bit of non-determinism, and I think a little is all you would need to
transform a horrible generator into a good practical one for many
applications.   I  think the lowest 2 or 3 (or more)  bits would appear to
modern processors as almost unpredictable since there is so much going on
inside modern computers that are unpredictable.
I don't know if the call to RDTSC is fast or how it would affect the
parallelism of todays modern machines.   I'm not particularly interested in
non-deterministic generators as I sometimes depend on this for testing and
debugging,  but it's an idea I thought I would throw out there.
- Don





Don Dailey wrote:

If you are looking for a cheap fast and simple random number generator,  A

post by George Marsaglia, an expert/guru on random number generation has
several and a C implemention.

These are one line generators,  coded as macros.He also discusses the

period and quality of each of them. This is a gem of a post  on
sci.stat.math,sci.math  if you are interested in RNG:

  http://www.math.niu.edu/~rusin/known-math/99/RNG

- Don



Heikki Levanto wrote:


In addition, xor_shift is better than builtin rand() and faster and
much smaller than MT.


I don't know that much about random numbers, so excuse my ignorance. But

a

bit of googling got me to the Park - Miller Minimal Standard random

number

generator

http://www.firstpr.com.au/dsp/rand31/p1192-park.pdf

From what I read, it should be quite sufficient for go programs. It is
dead simple and fast:

long int pmrand() {
   const long int a=16807;
   const long int m= ( 1  31 ) -1;
   pmrandseed = ( pmrandseed * a ) % m ;
   return pmrandseed;
} /* pmrand */


Should I worry about this not being good enough?
 - Heikki






___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/



___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/


___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/



___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/


Re: [computer-go] Random

2008-05-15 Thread Hideki Kato
Following url may help.
http://softwarecommunity.intel.com/isn/Community/en-US/forums/thread/30235396.aspx

-Hideki

Michael Williams: [EMAIL PROTECTED]:
I don't think Don was saying to use many calls to RDTSC to generate a single 
random number.
I think he meant do something like (FastBadRand() XOR RDTSC).
The first part has low quality low-order bits and the second part has low 
quality high-order 
bits.

Also, I can't imagine why executing a RDTSC would take 50 cycles.  But I 
couldn't find any 
docs on that aspect of the instruction.



steve uurtamo wrote:
 the only thing to watch is that you'll likely need
 30+ bits from these guys to seed a prng, and
 getting those bits in any organized way is likely
 going to happen on a regular schedule (i.e. if
 you get them in a loop, you're likely going to
 space them out in an organized way).
 
 s.
 
 
 On 5/15/08, Don Dailey [EMAIL PROTECTED] wrote:
 For a long time I have pondered whether you could build a very high quality
 random number generator that was extremely fast using the pentium RDTSC
 instruction as a low order bit entropy source. The idea would be to use
 an extremely fast (but low quality) pseudo random number generator,  but
 modify the output (or the internal state of the generator) with the time
 stamp register at each call.

 RDTSC reads the pentiums internal clock and is basically just a 64 bit
 counter.However it increments very quickly and could be viewed as an
 entropy source in the lowest bits as it would introduce at least a little
 bit of non-determinism, and I think a little is all you would need to
 transform a horrible generator into a good practical one for many
 applications.   I  think the lowest 2 or 3 (or more)  bits would appear to
 modern processors as almost unpredictable since there is so much going on
 inside modern computers that are unpredictable.
 I don't know if the call to RDTSC is fast or how it would affect the
 parallelism of todays modern machines.   I'm not particularly interested in
 non-deterministic generators as I sometimes depend on this for testing and
 debugging,  but it's an idea I thought I would throw out there.
 - Don





 Don Dailey wrote:
 If you are looking for a cheap fast and simple random number generator,  A
 post by George Marsaglia, an expert/guru on random number generation has
 several and a C implemention.
 These are one line generators,  coded as macros.He also discusses the
 period and quality of each of them. This is a gem of a post  on
 sci.stat.math,sci.math  if you are interested in RNG:
   http://www.math.niu.edu/~rusin/known-math/99/RNG

 - Don



 Heikki Levanto wrote:

 In addition, xor_shift is better than builtin rand() and faster and
 much smaller than MT.

 I don't know that much about random numbers, so excuse my ignorance. But
 a
 bit of googling got me to the Park - Miller Minimal Standard random
 number
 generator
 http://www.firstpr.com.au/dsp/rand31/p1192-park.pdf
 From what I read, it should be quite sufficient for go programs. It is
 dead simple and fast:

 long int pmrand() {
const long int a=16807;
const long int m= ( 1  31 ) -1;
pmrandseed = ( pmrandseed * a ) % m ;
return pmrandseed;
 } /* pmrand */


 Should I worry about this not being good enough?
  - Heikki





 ___
 computer-go mailing list
 computer-go@computer-go.org
 http://www.computer-go.org/mailman/listinfo/computer-go/


 ___
 computer-go mailing list
 computer-go@computer-go.org
 http://www.computer-go.org/mailman/listinfo/computer-go/

 ___
 computer-go mailing list
 computer-go@computer-go.org
 http://www.computer-go.org/mailman/listinfo/computer-go/
 

___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/
--
[EMAIL PROTECTED] (Kato)
___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/


Re: [computer-go] random numbers with functional languages

2007-12-19 Thread Stuart A. Yeates
Probably the reason that it is so slow is that it's aiming for a
cryptographically random number sequence. These are usually derived
ultimately from kernel timings (often via /dev/random on linux
systems) and it can take a while to establish a degree of confidence
in the randomness of these bits.

If you want a sequence of numbers that is very unlikely to repeat but
that doesn't have to be cryptographically random, standard practice is
to initialise the random number generator with the current time
(usually a long expressed in milliseconds). This naturally fails if
you ever create more than one sequence per millisecond.

cheers
stuart


On 19/12/2007, Berk Ozbozkurt [EMAIL PROTECTED] wrote:
 Hi,

 I'm currently writing a UCT based go program in Clean to see if it is
 feasible to write one in a functional language. This is my first attempt
 at functional languages, and I'm having trouble with random numbers.

 A mersenne twister module is available for Clean. Once initialized it is
 reasonably fast to extract a new random number from the generator.
 However, it is about a hundred times slower to initialize it with a new
 random seed. Therefore my first attempt at generating random numbers by
 storing seeds at tree nodes and creating a new random list and a new
 seed each time random numbers are required for mc evaluation is very
 slow. The alternative seems to be passing around an index to a global
 random list, which is both ugly and complicated. Is there another way?
 ___
 computer-go mailing list
 computer-go@computer-go.org
 http://www.computer-go.org/mailman/listinfo/computer-go/

___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/


Re: [computer-go] random numbers with functional languages

2007-12-19 Thread Imran Hendley
A couple of things I did:

I edited the Mersenne Twister code I'm using to get it's seed from the
system time in nanoseconds rather than in miliseconds to fix the problem of
wanting to generate more than one random number in a millisecond.

Instead of generating a new random number every time I want to pick a move
in a random playout, I fill a large circular array with random numbers when
my go program launches (before it is actually playing a game) and I have a
method that just gets the next number out of the array instead of generating
a new random number in real time. Actually I have a different array for each
possible board size, since I need a random integer from a different range
for each. Sure the array repeats after 500,000 numbers or however many you
use, but this is not a big deal when your playouts are only 100 moves long
each - and it is unlikely to start repeating from the same position. This
approach was much faster than generating random numbers on the fly.



On Dec 19, 2007 3:51 AM, Stuart A. Yeates [EMAIL PROTECTED] wrote:

 Probably the reason that it is so slow is that it's aiming for a
 cryptographically random number sequence. These are usually derived
 ultimately from kernel timings (often via /dev/random on linux
 systems) and it can take a while to establish a degree of confidence
 in the randomness of these bits.

 If you want a sequence of numbers that is very unlikely to repeat but
 that doesn't have to be cryptographically random, standard practice is
 to initialise the random number generator with the current time
 (usually a long expressed in milliseconds). This naturally fails if
 you ever create more than one sequence per millisecond.

 cheers
 stuart


 On 19/12/2007, Berk Ozbozkurt [EMAIL PROTECTED] wrote:
  Hi,
 
  I'm currently writing a UCT based go program in Clean to see if it is
  feasible to write one in a functional language. This is my first attempt
  at functional languages, and I'm having trouble with random numbers.
 
  A mersenne twister module is available for Clean. Once initialized it is
  reasonably fast to extract a new random number from the generator.
  However, it is about a hundred times slower to initialize it with a new
  random seed. Therefore my first attempt at generating random numbers by
  storing seeds at tree nodes and creating a new random list and a new
  seed each time random numbers are required for mc evaluation is very
  slow. The alternative seems to be passing around an index to a global
  random list, which is both ugly and complicated. Is there another way?
  ___
  computer-go mailing list
  computer-go@computer-go.org
  http://www.computer-go.org/mailman/listinfo/computer-go/
 
 ___
 computer-go mailing list
 computer-go@computer-go.org
 http://www.computer-go.org/mailman/listinfo/computer-go/

___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/

Re: [computer-go] random numbers with functional languages

2007-12-19 Thread Berk Ozbozkurt
That was not the problem, as the source code is available and it doesn't 
call system libraries at all. I was initializing with known seed in my 
tests anyway.


Thanks though, in the process of composing a reply demonstrating the 
problem, I found a partial solution. Now random number generation takes 
3% of running time, compared to 60% of older version and ~1% of a 
hypothetical ideal solution.


Berk.

Stuart A. Yeates wrote:

Probably the reason that it is so slow is that it's aiming for a
cryptographically random number sequence. These are usually derived
ultimately from kernel timings (often via /dev/random on linux
systems) and it can take a while to establish a degree of confidence
in the randomness of these bits.

If you want a sequence of numbers that is very unlikely to repeat but
that doesn't have to be cryptographically random, standard practice is
to initialise the random number generator with the current time
(usually a long expressed in milliseconds). This naturally fails if
you ever create more than one sequence per millisecond.

cheers
stuart


On 19/12/2007, Berk Ozbozkurt [EMAIL PROTECTED] wrote:
  

Hi,

I'm currently writing a UCT based go program in Clean to see if it is
feasible to write one in a functional language. This is my first attempt
at functional languages, and I'm having trouble with random numbers.

A mersenne twister module is available for Clean. Once initialized it is
reasonably fast to extract a new random number from the generator.
However, it is about a hundred times slower to initialize it with a new
random seed. Therefore my first attempt at generating random numbers by
storing seeds at tree nodes and creating a new random list and a new
seed each time random numbers are required for mc evaluation is very
slow. The alternative seems to be passing around an index to a global
random list, which is both ugly and complicated. Is there another way?



___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/


Re: [computer-go] random numbers with functional languages

2007-12-19 Thread Imran Hendley
A sorry about that. Glad to hear you fixed the problem. What was your
solution?

It seems you mentioned the global list approach in your email which I
missed too. Why did you think this was an ugly approach? I just put my
random array in a Singleton object (call it MyRandomNumberGenerator) which
internally stores the next index and has a method for getting the next
random number. So I just replace all my calls to Random.getNextInt() with
MyRandomNumberGenerator.getNextInt(). Actually I can see how a lot of people
would still call this ugly... But it's just a lookup so I think it will beat
any other solution that involves generating a new random number by a
reasonable margin.

On Dec 19, 2007 5:15 AM, Berk Ozbozkurt [EMAIL PROTECTED] wrote:

 That was not the problem, as the source code is available and it doesn't
 call system libraries at all. I was initializing with known seed in my
 tests anyway.

 Thanks though, in the process of composing a reply demonstrating the
 problem, I found a partial solution. Now random number generation takes
 3% of running time, compared to 60% of older version and ~1% of a
 hypothetical ideal solution.

 Berk.

 Stuart A. Yeates wrote:
  Probably the reason that it is so slow is that it's aiming for a
  cryptographically random number sequence. These are usually derived
  ultimately from kernel timings (often via /dev/random on linux
  systems) and it can take a while to establish a degree of confidence
  in the randomness of these bits.
 
  If you want a sequence of numbers that is very unlikely to repeat but
  that doesn't have to be cryptographically random, standard practice is
  to initialise the random number generator with the current time
  (usually a long expressed in milliseconds). This naturally fails if
  you ever create more than one sequence per millisecond.
 
  cheers
  stuart
 
 
  On 19/12/2007, Berk Ozbozkurt [EMAIL PROTECTED] wrote:
 
  Hi,
 
  I'm currently writing a UCT based go program in Clean to see if it is
  feasible to write one in a functional language. This is my first
 attempt
  at functional languages, and I'm having trouble with random numbers.
 
  A mersenne twister module is available for Clean. Once initialized it
 is
  reasonably fast to extract a new random number from the generator.
  However, it is about a hundred times slower to initialize it with a new
  random seed. Therefore my first attempt at generating random numbers by
  storing seeds at tree nodes and creating a new random list and a new
  seed each time random numbers are required for mc evaluation is very
  slow. The alternative seems to be passing around an index to a global
  random list, which is both ugly and complicated. Is there another way?
 

 ___
 computer-go mailing list
 computer-go@computer-go.org
 http://www.computer-go.org/mailman/listinfo/computer-go/

___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/

Re: [computer-go] random numbers with functional languages

2007-12-19 Thread Berk Ozbozkurt
Your solution would still be way faster, as I still have to generate a 
new random number every time I need one.


The problem is lack of side effects in Clean. If I stick to functional 
programming paradigm -and that is the whole point of my effort- I can't 
write  function which returns a different number each time it is called. 
A function is supposed to return same result every time it is called 
with same parameters so I can't/shouldn't write an analogue of 
getNextInt() (whether or not getNextInt() returns a number from a list 
or from a random number generator.)


I just shaved off time by not initializing a new random generator each 
time a node is visited. Instead, when a leaf node is visited, first 
maxMoves terms of random list is sent to MC evaluation, and remaining 
terms are used to create a new list. Sharing this list across whole 
search tree would be ugly and complicated. So I still initialize a new 
random list for each new tree node but reuse it for subsequent MC 
evaluations from that node.


Berk.

Imran Hendley wrote:
A sorry about that. Glad to hear you fixed the problem. What was your 
solution?


It seems you mentioned the global list approach in your email which 
I missed too. Why did you think this was an ugly approach? I just put 
my random array in a Singleton object (call it 
MyRandomNumberGenerator) which internally stores the next index and 
has a method for getting the next random number. So I just replace all 
my calls to Random.getNextInt() with 
MyRandomNumberGenerator.getNextInt(). Actually I can see how a lot of 
people would still call this ugly... But it's just a lookup so I think 
it will beat any other solution that involves generating a new random 
number by a reasonable margin.


On Dec 19, 2007 5:15 AM, Berk Ozbozkurt [EMAIL PROTECTED] 
mailto:[EMAIL PROTECTED] wrote:


That was not the problem, as the source code is available and it
doesn't
call system libraries at all. I was initializing with known seed in my
tests anyway.

Thanks though, in the process of composing a reply demonstrating the
problem, I found a partial solution. Now random number generation
takes
3% of running time, compared to 60% of older version and ~1% of a
hypothetical ideal solution.

Berk.

Stuart A. Yeates wrote:
 Probably the reason that it is so slow is that it's aiming for a
 cryptographically random number sequence. These are usually derived
 ultimately from kernel timings (often via /dev/random on linux
 systems) and it can take a while to establish a degree of confidence
 in the randomness of these bits.

 If you want a sequence of numbers that is very unlikely to
repeat but
 that doesn't have to be cryptographically random, standard
practice is
 to initialise the random number generator with the current time
 (usually a long expressed in milliseconds). This naturally fails if
 you ever create more than one sequence per millisecond.

 cheers
 stuart


 On 19/12/2007, Berk Ozbozkurt [EMAIL PROTECTED]
mailto:[EMAIL PROTECTED] wrote:

 Hi,

 I'm currently writing a UCT based go program in Clean to see if
it is
 feasible to write one in a functional language. This is my
first attempt
 at functional languages, and I'm having trouble with random
numbers.

 A mersenne twister module is available for Clean. Once
initialized it is
 reasonably fast to extract a new random number from the generator.
 However, it is about a hundred times slower to initialize it
with a new
 random seed. Therefore my first attempt at generating random
numbers by
 storing seeds at tree nodes and creating a new random list and
a new
 seed each time random numbers are required for mc evaluation is
very
 slow. The alternative seems to be passing around an index to a
global
 random list, which is both ugly and complicated. Is there
another way?




___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/


Re: [computer-go] random numbers with functional languages

2007-12-19 Thread Don Dailey
Berk,

Why do you need to initialize the seed more than 1 time?You should
use zobrist hashing.   

Initialize the random number generator once when you start the programs.

Fill an array with random numbers from the generator at program startup
too.  The array looks something like this for a 9x9 board:

  zob[3][81]   

Basically xor each point of the 9x9 board with the random number on the
point.  The first index is 3 because I assume you have white/black/empty
points.So xor the appropriate one for each point.

A major enhancement is that you can do this incrementally.   You have a
master key that you keep up to date.  If you add a stone to the board, 
you can update the key with only 2 xor operations.Since the point is
no longer empty you must undo  the xor with the empty point.XOR is
great because you can undo it with the same xor operation.So you get:

   if mv is the move you are about to make with a black stone then:

 master_hash = master_hash ^ zob[EMPTY][ mv ] 
 master_hash = master_hash ^ zob[BLACK][ mv ]

and you are done.   Of course if a white group is captured,  you must
undo all the white stones that were captured in some kind of loop,  but
it still runs rings around updating the entire board on each move.

There is a variation of this - you can choose to hash only 2 colors: 
(black and empty), (white and empty), or (black and white) and so the
other color is inferred.The natural expression of this in a program
is to hash only white and black because you never change state from
black to white in a single move.

- Don




Berk Ozbozkurt wrote:
 Hi,

 I'm currently writing a UCT based go program in Clean to see if it is
 feasible to write one in a functional language. This is my first
 attempt at functional languages, and I'm having trouble with random
 numbers.

 A mersenne twister module is available for Clean. Once initialized it
 is reasonably fast to extract a new random number from the generator.
 However, it is about a hundred times slower to initialize it with a
 new random seed. Therefore my first attempt at generating random
 numbers by storing seeds at tree nodes and creating a new random list
 and a new seed each time random numbers are required for mc evaluation
 is very slow. The alternative seems to be passing around an index to a
 global random list, which is both ugly and complicated. Is there
 another way?
 ___
 computer-go mailing list
 computer-go@computer-go.org
 http://www.computer-go.org/mailman/listinfo/computer-go/

___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/


Re: [computer-go] random numbers with functional languages

2007-12-19 Thread Jason House
On Dec 19, 2007 10:24 AM, Don Dailey [EMAIL PROTECTED] wrote:

 Why do you need to initialize the seed more than 1 time?You should
 use zobrist hashing.



By design, my program reinitializes the random seeds.  This is done at the
start of each genmove and is intended for repeatability.
___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/

Re: [computer-go] random numbers with functional languages

2007-12-19 Thread Don Dailey

 Instead of generating a new random number every time I want to pick a
 move in a random playout, I fill a large circular array with random
 numbers when my go program launches (before it is actually playing a
 game) and I have a method that just gets the next number out of the
 array instead of generating a new random number in real time. Actually
 I have a different array for each possible board size, since I need a
 random integer from a different range for each. Sure the array repeats
 after 500,000 numbers or however many you use, but this is not a big
 deal when your playouts are only 100 moves long each - and it is
 unlikely to start repeating from the same position. This approach was
 much faster than generating random numbers on the fly.

That could affect your caches.   This is generally the type of thing
that can create unexpected problems if you are not very careful.   You
have essentially just created a very low period RNG.  I would not
play long autotest matches unless you re-initalize this before each
game.I would also hope that you have enough to get you through a
complete game (or nearly so.)  Then you might get away with it.

Years ago a wrote a rummy card game player and was testing different
strategies against each other.   I discovered that the RNG was low
period and was getting consistently biased results (where identical
programs were not scoring 50/50 but more like 52/48 over thousands of
games.)It turned out to be the short period of the RNG causing the
problem.It's very difficult if not impossible to predict how this
will affect the period of your application. You could fall into a
winning or losing cycle against another similarly deterministic player
and it could be short or fairly long.   (A cycle where you will lose or
win more games than you should and games will repeat.)  This
behavior is guaranteed, it's a just a matter of how long or short the
cycle will be.

I improved the problem with the card game by adding more chaos.   It
wasn't the ideal solution but it was an improvement.Instead of
re-initializing a new pack of cards,  I kept the old pack around and
re-shuffled it.   Effectively,  this is like creating a slightly more
sophisticated RNG with a longer period. So each new game began with
a deck of cards that were in chaos from the previous game (similar to
real card games.)  

I'm surprised that this represents a large speedup.   How long does it
take to initialize a new set of random numbers?   I would think this
would happen very quickly.   However long it takes,  I would think that
an upper bound on how much time you can save (minus some caching effects
perhaps) would be this same time spent building a new set of numbers.  
So if it takes about 5 seconds,  you should only lose about 5 seconds
for the whole game assuming you initialized just enough numbers to play
a full game.

- Don




 On Dec 19, 2007 3:51 AM, Stuart A. Yeates [EMAIL PROTECTED]
 mailto:[EMAIL PROTECTED] wrote:

 Probably the reason that it is so slow is that it's aiming for a
 cryptographically random number sequence. These are usually derived
 ultimately from kernel timings (often via /dev/random on linux
 systems) and it can take a while to establish a degree of confidence
 in the randomness of these bits.

 If you want a sequence of numbers that is very unlikely to repeat but
 that doesn't have to be cryptographically random, standard practice is
 to initialise the random number generator with the current time
 (usually a long expressed in milliseconds). This naturally fails if
 you ever create more than one sequence per millisecond.

 cheers
 stuart


 On 19/12/2007, Berk Ozbozkurt [EMAIL PROTECTED]
 mailto:[EMAIL PROTECTED] wrote:
  Hi,
 
  I'm currently writing a UCT based go program in Clean to see if
 it is
  feasible to write one in a functional language. This is my first
 attempt
  at functional languages, and I'm having trouble with random numbers.
 
  A mersenne twister module is available for Clean. Once
 initialized it is
  reasonably fast to extract a new random number from the generator.
  However, it is about a hundred times slower to initialize it
 with a new
  random seed. Therefore my first attempt at generating random
 numbers by
  storing seeds at tree nodes and creating a new random list and a new
  seed each time random numbers are required for mc evaluation is very
  slow. The alternative seems to be passing around an index to a
 global
  random list, which is both ugly and complicated. Is there
 another way?
  ___
  computer-go mailing list
  computer-go@computer-go.org mailto:computer-go@computer-go.org
  http://www.computer-go.org/mailman/listinfo/computer-go/
 
 ___
 computer-go 

Re: [computer-go] random numbers with functional languages

2007-12-19 Thread Don Dailey
Hold on,  I just re-read this.Do you think you must initialize the
generator after each number?   You only need to initialize MT once, when
your program starts and then it will provide very good numbers for the
next several billion years.

- Don


Imran Hendley wrote:
 A couple of things I did:

 I edited the Mersenne Twister code I'm using to get it's seed from the
 system time in nanoseconds rather than in miliseconds to fix the
 problem of wanting to generate more than one random number in a
 millisecond.

 Instead of generating a new random number every time I want to pick a
 move in a random playout, I fill a large circular array with random
 numbers when my go program launches (before it is actually playing a
 game) and I have a method that just gets the next number out of the
 array instead of generating a new random number in real time. Actually
 I have a different array for each possible board size, since I need a
 random integer from a different range for each. Sure the array repeats
 after 500,000 numbers or however many you use, but this is not a big
 deal when your playouts are only 100 moves long each - and it is
 unlikely to start repeating from the same position. This approach was
 much faster than generating random numbers on the fly.



 On Dec 19, 2007 3:51 AM, Stuart A. Yeates [EMAIL PROTECTED]
 mailto:[EMAIL PROTECTED] wrote:

 Probably the reason that it is so slow is that it's aiming for a
 cryptographically random number sequence. These are usually derived
 ultimately from kernel timings (often via /dev/random on linux
 systems) and it can take a while to establish a degree of confidence
 in the randomness of these bits.

 If you want a sequence of numbers that is very unlikely to repeat but
 that doesn't have to be cryptographically random, standard practice is
 to initialise the random number generator with the current time
 (usually a long expressed in milliseconds). This naturally fails if
 you ever create more than one sequence per millisecond.

 cheers
 stuart


 On 19/12/2007, Berk Ozbozkurt [EMAIL PROTECTED]
 mailto:[EMAIL PROTECTED] wrote:
  Hi,
 
  I'm currently writing a UCT based go program in Clean to see if
 it is
  feasible to write one in a functional language. This is my first
 attempt
  at functional languages, and I'm having trouble with random numbers.
 
  A mersenne twister module is available for Clean. Once
 initialized it is
  reasonably fast to extract a new random number from the generator.
  However, it is about a hundred times slower to initialize it
 with a new
  random seed. Therefore my first attempt at generating random
 numbers by
  storing seeds at tree nodes and creating a new random list and a new
  seed each time random numbers are required for mc evaluation is very
  slow. The alternative seems to be passing around an index to a
 global
  random list, which is both ugly and complicated. Is there
 another way?
  ___
  computer-go mailing list
  computer-go@computer-go.org mailto:computer-go@computer-go.org
  http://www.computer-go.org/mailman/listinfo/computer-go/
 
 ___
 computer-go mailing list
 computer-go@computer-go.org mailto:computer-go@computer-go.org
 http://www.computer-go.org/mailman/listinfo/computer-go/
 http://www.computer-go.org/mailman/listinfo/computer-go/


 

 ___
 computer-go mailing list
 computer-go@computer-go.org
 http://www.computer-go.org/mailman/listinfo/computer-go/
___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/


Re: [computer-go] random numbers with functional languages

2007-12-19 Thread Don Dailey

Imran Hendley wrote:
 A sorry about that. Glad to hear you fixed the problem. What was your
 solution?

 It seems you mentioned the global list approach in your email which
 I missed too. Why did you think this was an ugly approach? I just put
 my random array in a Singleton object (call it
 MyRandomNumberGenerator) which internally stores the next index and
 has a method for getting the next random number. So I just replace all
 my calls to Random.getNextInt() with
 MyRandomNumberGenerator.getNextInt(). Actually I can see how a lot of
 people would still call this ugly... But it's just a lookup so I think
 it will beat any other solution that involves generating a new random
 number by a reasonable margin.
You are spending time before the game to save time during the game - a
good principle in general but you do have a few issues:

   1.  How does this affect cache?   (probably not much but you have to
consider it.)
   2.  Can you get enough numbers to last a complete game?

If this is so slow,  then there would be a long delay each time you
generate a new set of random numbers and I really think you should do
this between games. I wonder how long the delay is?

If the delay is unduly long (it must be, otherwise you wouldn't have to
do this)  then an alternative is to change a fraction of the numbers
between games:

   // code to randomly change 1000 values:

   for (i=0; i1000; i++) {
ix = randomInt( RANDOM_ARRAY_SIZE );
randArray[ ix ] = newRandomNumber();
   }

In other words, pick a few array locations at random and change their
value.  

This will prevent any serious cycles with long testing sequences.   

You could also perform such a routine between moves.   You only need to
change a few so change as many as you can in a fraction of a second. 

- Don




 On Dec 19, 2007 5:15 AM, Berk Ozbozkurt [EMAIL PROTECTED]
 mailto:[EMAIL PROTECTED] wrote:

 That was not the problem, as the source code is available and it
 doesn't
 call system libraries at all. I was initializing with known seed in my
 tests anyway.

 Thanks though, in the process of composing a reply demonstrating the
 problem, I found a partial solution. Now random number generation
 takes
 3% of running time, compared to 60% of older version and ~1% of a
 hypothetical ideal solution.

 Berk.

 Stuart A. Yeates wrote:
  Probably the reason that it is so slow is that it's aiming for a
  cryptographically random number sequence. These are usually derived
  ultimately from kernel timings (often via /dev/random on linux
  systems) and it can take a while to establish a degree of confidence
  in the randomness of these bits.
 
  If you want a sequence of numbers that is very unlikely to
 repeat but
  that doesn't have to be cryptographically random, standard
 practice is
  to initialise the random number generator with the current time
  (usually a long expressed in milliseconds). This naturally fails if
  you ever create more than one sequence per millisecond.
 
  cheers
  stuart
 
 
  On 19/12/2007, Berk Ozbozkurt [EMAIL PROTECTED]
 mailto:[EMAIL PROTECTED] wrote:
 
  Hi,
 
  I'm currently writing a UCT based go program in Clean to see if
 it is
  feasible to write one in a functional language. This is my
 first attempt
  at functional languages, and I'm having trouble with random
 numbers.
 
  A mersenne twister module is available for Clean. Once
 initialized it is
  reasonably fast to extract a new random number from the generator.
  However, it is about a hundred times slower to initialize it
 with a new
  random seed. Therefore my first attempt at generating random
 numbers by
  storing seeds at tree nodes and creating a new random list and
 a new
  seed each time random numbers are required for mc evaluation is
 very
  slow. The alternative seems to be passing around an index to a
 global
  random list, which is both ugly and complicated. Is there
 another way?
 

 ___
 computer-go mailing list
 computer-go@computer-go.org mailto:computer-go@computer-go.org
 http://www.computer-go.org/mailman/listinfo/computer-go/


 

 ___
 computer-go mailing list
 computer-go@computer-go.org
 http://www.computer-go.org/mailman/listinfo/computer-go/
___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/


Re: [computer-go] random numbers with functional languages

2007-12-19 Thread Imran Hendley
On Dec 19, 2007 11:25 AM, Don Dailey [EMAIL PROTECTED] wrote:


 Imran Hendley wrote:
  A sorry about that. Glad to hear you fixed the problem. What was your
  solution?
 
  It seems you mentioned the global list approach in your email which
  I missed too. Why did you think this was an ugly approach? I just put
  my random array in a Singleton object (call it
  MyRandomNumberGenerator) which internally stores the next index and
  has a method for getting the next random number. So I just replace all
  my calls to Random.getNextInt() with
  MyRandomNumberGenerator.getNextInt(). Actually I can see how a lot of
  people would still call this ugly... But it's just a lookup so I think
  it will beat any other solution that involves generating a new random
  number by a reasonable margin.
 You are spending time before the game to save time during the game - a
 good principle in general but you do have a few issues:

   1.  How does this affect cache?   (probably not much but you have to
 consider it.)
   2.  Can you get enough numbers to last a complete game?

 If this is so slow,  then there would be a long delay each time you
 generate a new set of random numbers and I really think you should do
 this between games. I wonder how long the delay is?

 If the delay is unduly long (it must be, otherwise you wouldn't have to
 do this)  then an alternative is to change a fraction of the numbers
 between games:

   // code to randomly change 1000 values:

   for (i=0; i1000; i++) {
ix = randomInt( RANDOM_ARRAY_SIZE );
randArray[ ix ] = newRandomNumber();
   }

 In other words, pick a few array locations at random and change their
 value.

 This will prevent any serious cycles with long testing sequences.

 You could also perform such a routine between moves.   You only need to
 change a few so change as many as you can in a fraction of a second.

 - Don


Don,

I probably go through my entire array 5 times per second during a UCT
search. So far I have been relying on the hope that I do not come back to
the beginning of my array at exactly the same position in a random playout
which would cause a bad cycle. If I come back at a different position then I
will not start replaying the same set of playouts in the search of that
particular game position, and I will also play a different sequence of moves
in this run through the array because I will reject different numbers I
get because they correspond to illegal board positions but didn't last time
through the array and vice versa.

I think the chance of a bad cycle is very small. I just did some more
analysis of this just now and it got a little complicated, so I'll leave it
out. However, I do think making a bad cycle impossible is important. Your
idea of reinitializing some random positions in the array looks really good.
Unfortunately there is no way I can do this each time through the array for
any meaningful portion of the whole array...since just resetting my index to
0 when I get to the end is pretty expensive in terms of average cost, and if
I'm going through the array a few times a second I can't do much more than
that each time. What do you think of resetting my index to a random position
between 0 and some small n every time to make the probability of getting
stuck in a cycle forever go to zero, and then finding some free time to
reset the numbers like right after playing a move and before starting to
ponder for example?

And about the cache...I've never really thought about it. How do think the
cache would be affected? I don't really know much about cache's to be
honest. Are you saying that the numbers in my array would get stored in the
cache? Is this good or bad?

Imran
___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/

Re: [computer-go] random numbers with functional languages

2007-12-19 Thread Chris Fant
Yes, the large amount of state in a playout will probably enable you
to safely get away with what you are doing, but I would certainly want
to test the overall strength of the engine using this method this
versus using the straight-forward method of seeding the RNG once and
generating a new random number anytime you need it.
___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/


Re: [computer-go] random numbers with functional languages

2007-12-19 Thread Don Dailey

 I probably go through my entire array 5 times per second during a UCT
 search. So far I have been relying on the hope that I do not come back
 to the beginning of my array at exactly the same position in a random
 playout which would cause a bad cycle. If I come back at a different
 position then I will not start replaying the same set of playouts in
 the search of that particular game position, and I will also play a
 different sequence of moves in this run through the array because I
 will reject different numbers I get because they correspond to
 illegal board positions but didn't last time through the array and
 vice versa.

 I think the chance of a bad cycle is very small.
Hopefully that is true.  

 I just did some more analysis of this just now and it got a little
 complicated, so I'll leave it out. However, I do think making a bad
 cycle impossible is important. Your idea of reinitializing some random
 positions in the array looks really good. Unfortunately there is no
 way I can do this each time through the array for any meaningful
 portion of the whole array...since just resetting my index to 0 when I
 get to the end is pretty expensive in terms of average cost, and if
 I'm going through the array a few times a second I can't do much more
 than that each time. What do you think of resetting my index to a
 random position between 0 and some small n every time to make the
 probability of getting stuck in a cycle forever go to zero, and then
 finding some free time to reset the numbers like right after playing a
 move and before starting to ponder for example?
Certainly that's better than nothing.   I assume you will use the random
number generator to do this?   If so, it will be an improvement.

 And about the cache...I've never really thought about it. How do think
 the cache would be affected? I don't really know much about cache's to
 be honest. Are you saying that the numbers in my array would get
 stored in the cache? Is this good or bad?
If you use a lot of memory to store something that could be generated on
the fly,  you could slow your whole program down due to caching issues
between the processor and memory.When you use a piece of data for
the first time,  it is slow.   But after that it is much faster because
it is stored in super-fast memory.   But you only have so much of that
super-fast memory. I don't think it's likely to be an issue for
you,  but it's something to keep in mind.  I have created cache
unfriendly software by going too crazy with tables but modern processors
are pretty well designed and generous.

- Don



 Imran
 

 ___
 computer-go mailing list
 computer-go@computer-go.org
 http://www.computer-go.org/mailman/listinfo/computer-go/
___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/


Re: [computer-go] Random move selection (was) Crazystone patterns

2007-09-21 Thread dhillismail

Good information. Thanks.



- Dave Hillis


-Original Message-
From: Jacques Basaldúa [EMAIL PROTECTED]
To: computer-go@computer-go.org
Sent: Fri, 21 Sep 2007 7:44 am
Subject: [computer-go] Random move selection (was) Crazystone patterns



Dave Hillis, wrote: 
 
 Suppose I can generate scores for all of the moves quickly enough.  I still 
 face the problem of quickly choosing a move biased by the  scores. 
 Tournament selection is fast, but that is a function of  relative ranking of 
 the scores, not the values of the scores.  Roulette wheel selection gives me 
 an answer, but it is slow slow  slow, the way I implement it anyway. Can 
 anybody describe a good  way to do this? 
 
We posted about that before this summer when I was implementing it. 
I proposed a ticket based lottery, but that, of course, restricts 
the difference to small values. It can be implemented using a linked 
list so that each extra ticket allocation cost few clock cycles (I don't 
remember exactly how many, but less than 10 asm instruction for sure). 
 
My final version uses 2 values for the tickets HI and LO where 
 
1 HI = 32 LO 
 
The default (when the pattern is not in the database) is 1 HI. 
 
The score goes from 1 (= 1 LO) to 1024 (= 32 HI). If you round the scores 
it the database to avoid such values as 927 (= 28 HI, 31 LO) and round it as 
928 (= 29 HI) you can have a nice dynamic range from default/32 to 
default*32 having not too many tickets to allocate. 
 
Jacques. 
 
PD. Search the threads (about May-June 2007) because other good ideas were 
proposed. Binary trees, etc. 
 
___ 
computer-go mailing list 
[EMAIL PROTECTED]
http://www.computer-go.org/mailman/listinfo/computer-go/ 



Check Out the new free AIM(R) Mail -- Unlimited storage and industry-leading 
spam and email virus protection.
___
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/