Right, I was talking about something else. Yes it's negligible, only 16% slower with uniform dist (that's pointless anyway in this case).matthewlai wrote:I meant using uniform_int_distribution on top of the RNG vs RNG directly.
Magic number generation taking 17 seconds or more
Moderators: hgm, Dann Corbit, Harvey Williamson
-
mar
- Posts: 2552
- Joined: Fri Nov 26, 2010 2:00 pm
- Location: Czech Republic
- Full name: Martin Sedlak
Re: Magic number generation taking 17 seconds or more
-
krismchess
- Posts: 24
- Joined: Tue Oct 13, 2015 2:52 am
Re: Magic number generation taking 17 seconds or more
Where can I get a KISS PRNG examples?
And how should I find the seed numbers to them?
And how should I find the seed numbers to them?
--
Thanks,
Kalyan
Never Give UP!
Thanks,
Kalyan
Never Give UP!
-
krismchess
- Posts: 24
- Joined: Tue Oct 13, 2015 2:52 am
Re: Magic number generation taking 17 seconds or more
Hi Gerd,
That's what I was exactly looking for.
Thanks!
That's what I was exactly looking for.
Thanks!
Gerd Isenberg wrote:The precondition for a good "sparse random" magic factor seems that the upper byte of the 64-bit product with the relevant occupancy mask has at least 6 bits set, so that the index distribution for all subset masks promises a good collision property. I guess the trick largely depends on properties of the used PRNG and seed. I'll suggest to profile how long it takes for every rook and bishop square, how often it loops per square in the first do while popcount loop, and how many trials are used at all per square and piece to find a destructive collision free magic.
--
Thanks,
Kalyan
Never Give UP!
Thanks,
Kalyan
Never Give UP!
-
mar
- Posts: 2552
- Joined: Fri Nov 26, 2010 2:00 pm
- Location: Czech Republic
- Full name: Martin Sedlak
Re: Magic number generation taking 17 seconds or more
Bob Jenkins' pages: http://burtleburtle.net/bob/rand/smallprng.htmlkrismchess wrote:Where can I get a KISS PRNG examples?
And how should I find the seed numbers to them?
Alternatively you could use mine (public domain):
Code: Select all
class FastRandom
{
inline ULong Rotate( ULong v, Byte s ) {
return (v >> s) | (v << (64-s));
}
public:
FastRandom() {
Seed(0);
}
// generate next 64-bit random number
inline ULong Next()
{
ULong tmp = keys[0];
keys[0] += Rotate( keys[1] ^ 0xc5462216u ^ ((ULong)0xcf14f4ebu<<32), 1 );
return keys[1] += Rotate( tmp ^ 0x75ecfc58u ^ ((ULong)0x9576080cu<<32), 9 );
}
void Seed( ULong val )
{
keys[0] = keys[1] = val;
for ( Int i=0; i<64; i++ ) {
Next();
}
}
private:
ULong keys[2];
};
Passes dieharder tests, used by a couple of people for various things (a friend used it as part of a fast mesh simplification algorithm to choose edge collapses)
keys is IV and you can simply seed the internal state with std:: random generators/whatever and choose the one which works best for you.
Performance depends on the ability of your compiler to fold the rotations; IIRC clang had some problems, but I don't remember exactly.
-
AlvaroBegue
- Posts: 931
- Joined: Tue Mar 09, 2010 3:46 pm
- Location: New York
- Full name: Álvaro Begué (RuyDos)
Re: Magic number generation taking 17 seconds or more
What's the problem with it taking 17 seconds? I think mine took several minutes, but I don't even have the code anymore. I took the output, hard-coded it into my program and I never need to run that code again.
-
krismchess
- Posts: 24
- Joined: Tue Oct 13, 2015 2:52 am
Re: Magic number generation taking 17 seconds or more
If there is a room for improvement why shouldn't I improve it?
AlvaroBegue wrote:What's the problem with it taking 17 seconds? I think mine took several minutes, but I don't even have the code anymore. I took the output, hard-coded it into my program and I never need to run that code again.
--
Thanks,
Kalyan
Never Give UP!
Thanks,
Kalyan
Never Give UP!
-
krismchess
- Posts: 24
- Joined: Tue Oct 13, 2015 2:52 am
Re: Magic number generation taking 17 seconds or more
I will try this one from Bob Jenkins' pages & your FastRandom.
Meanwhile I tried to use a KISS PRNG & the C++ <random> lib using random_device, uniform_int_distribution & mt19937_64 and found the <random> lib is consistent with 3 seconds while KISS PRNG is taking a bit longer. Full code below:
Meanwhile I tried to use a KISS PRNG & the C++ <random> lib using random_device, uniform_int_distribution & mt19937_64 and found the <random> lib is consistent with 3 seconds while KISS PRNG is taking a bit longer. Full code below:
Code: Select all
class Random {
private:
std::random_device rd;
std::mt19937_64 mt;
std::uniform_int_distribution<uint64_t> dist;
public:
Random() : rd(),mt(rd()),dist() {
}
uint64_t next() {
return dist(mt);
}
};
// A KISS PRNG
typedef uint64_t uint64;
uint64 x = uint64(123456789123);
uint64 y = uint64(987654321987);
uint64 z1 = uint64(43219876);
uint64 c1 = uint64(6543217);
uint64 z2 = uint64(21987643);
uint64 c2 = uint64(1732654);
uint64 rand64();
uint64 rand64()
{
uint64 t;
x = uint64(1490024343005336237) * x + 123456789;
y ^= y << 21; y ^= y >> 17; y ^= y << 30; /* Do not set y=0! */
t = uint64(4294584393) * z1 + c1; c1 = t >> 32; z1 = t;
t = uint64(4246477509) * z2 + c2; c2 = t >> 32; z2 = t;
return x + y + z1 + ((uint64)z2 << 32); /* Return 64-bit result */
}mar wrote:Bob Jenkins' pages: http://burtleburtle.net/bob/rand/smallprng.htmlkrismchess wrote:Where can I get a KISS PRNG examples?
And how should I find the seed numbers to them?
Alternatively you could use mine (public domain):
ULong = uint64_t, Byte = uint8_tCode: Select all
class FastRandom { inline ULong Rotate( ULong v, Byte s ) { return (v >> s) | (v << (64-s)); } public: FastRandom() { Seed(0); } // generate next 64-bit random number inline ULong Next() { ULong tmp = keys[0]; keys[0] += Rotate( keys[1] ^ 0xc5462216u ^ ((ULong)0xcf14f4ebu<<32), 1 ); return keys[1] += Rotate( tmp ^ 0x75ecfc58u ^ ((ULong)0x9576080cu<<32), 9 ); } void Seed( ULong val ) { keys[0] = keys[1] = val; for ( Int i=0; i<64; i++ ) { Next(); } } private: ULong keys[2]; };
Passes dieharder tests, used by a couple of people for various things (a friend used it as part of a fast mesh simplification algorithm to choose edge collapses)
keys is IV and you can simply seed the internal state with std:: random generators/whatever and choose the one which works best for you.
Performance depends on the ability of your compiler to fold the rotations; IIRC clang had some problems, but I don't remember exactly.
Code: Select all
--
Thanks,
Kalyan
Never Give UP!
Thanks,
Kalyan
Never Give UP!
-
AlvaroBegue
- Posts: 931
- Joined: Tue Mar 09, 2010 3:46 pm
- Location: New York
- Full name: Álvaro Begué (RuyDos)
Re: Magic number generation taking 17 seconds or more
I still don't understand. Are you running this search every time the engine is started? Why? Having a hard-coded table with all the magic multipliers takes exactly 3,072 bytes in my executable, and I can skip having and running the generating code.krismchess wrote:If there is a room for improvement why shouldn't I improve it?
-
krismchess
- Posts: 24
- Joined: Tue Oct 13, 2015 2:52 am
Re: Magic number generation taking 17 seconds or more
Hard coding isn't a good practice. If I can compute it in a negligible amount of time (that too one time) during startup why should I ignore it? Every time I run my engine I will have a unique set of magic's isn't it?
AlvaroBegue wrote:I still don't understand. Are you running this search every time the engine is started? Why? Having a hard-coded table with all the magic multipliers takes exactly 3,072 bytes in my executable, and I can skip having and running the generating code.krismchess wrote:If there is a room for improvement why shouldn't I improve it?
--
Thanks,
Kalyan
Never Give UP!
Thanks,
Kalyan
Never Give UP!
-
krismchess
- Posts: 24
- Joined: Tue Oct 13, 2015 2:52 am
Re: Magic number generation taking 17 seconds or more
Hi Mar,
FastRandom - is really *FAST*. It goes through in 2 seconds time (consistent when I ran it for a dozen of times). Can you post some theory behind this - how it works etc.?
Also Do you allow me to use your FastRandom code in my chess engine & I'll provide this forum reference & your name in the code comments & README notes.
Many thanks.
FastRandom - is really *FAST*. It goes through in 2 seconds time (consistent when I ran it for a dozen of times). Can you post some theory behind this - how it works etc.?
Also Do you allow me to use your FastRandom code in my chess engine & I'll provide this forum reference & your name in the code comments & README notes.
Many thanks.
krismchess wrote:I will try this one from Bob Jenkins' pages & your FastRandom.
Meanwhile I tried to use a KISS PRNG & the C++ <random> lib using random_device, uniform_int_distribution & mt19937_64 and found the <random> lib is consistent with 3 seconds while KISS PRNG is taking a bit longer. Full code below:Code: Select all
class Random { private: std::random_device rd; std::mt19937_64 mt; std::uniform_int_distribution<uint64_t> dist; public: Random() : rd(),mt(rd()),dist() { } uint64_t next() { return dist(mt); } }; // A KISS PRNG typedef uint64_t uint64; uint64 x = uint64(123456789123); uint64 y = uint64(987654321987); uint64 z1 = uint64(43219876); uint64 c1 = uint64(6543217); uint64 z2 = uint64(21987643); uint64 c2 = uint64(1732654); uint64 rand64(); uint64 rand64() { uint64 t; x = uint64(1490024343005336237) * x + 123456789; y ^= y << 21; y ^= y >> 17; y ^= y << 30; /* Do not set y=0! */ t = uint64(4294584393) * z1 + c1; c1 = t >> 32; z1 = t; t = uint64(4246477509) * z2 + c2; c2 = t >> 32; z2 = t; return x + y + z1 + ((uint64)z2 << 32); /* Return 64-bit result */ }mar wrote:Bob Jenkins' pages: http://burtleburtle.net/bob/rand/smallprng.htmlkrismchess wrote:Where can I get a KISS PRNG examples?
And how should I find the seed numbers to them?
Alternatively you could use mine (public domain):
ULong = uint64_t, Byte = uint8_tCode: Select all
class FastRandom { inline ULong Rotate( ULong v, Byte s ) { return (v >> s) | (v << (64-s)); } public: FastRandom() { Seed(0); } // generate next 64-bit random number inline ULong Next() { ULong tmp = keys[0]; keys[0] += Rotate( keys[1] ^ 0xc5462216u ^ ((ULong)0xcf14f4ebu<<32), 1 ); return keys[1] += Rotate( tmp ^ 0x75ecfc58u ^ ((ULong)0x9576080cu<<32), 9 ); } void Seed( ULong val ) { keys[0] = keys[1] = val; for ( Int i=0; i<64; i++ ) { Next(); } } private: ULong keys[2]; };
Passes dieharder tests, used by a couple of people for various things (a friend used it as part of a fast mesh simplification algorithm to choose edge collapses)
keys is IV and you can simply seed the internal state with std:: random generators/whatever and choose the one which works best for you.
Performance depends on the ability of your compiler to fold the rotations; IIRC clang had some problems, but I don't remember exactly.Code: Select all
--
Thanks,
Kalyan
Never Give UP!
Thanks,
Kalyan
Never Give UP!