-
Notifications
You must be signed in to change notification settings - Fork 4.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix System.Random algorithm bug #6203
Comments
I think we should fix this for CoreCLR. The fix should be made under Also, the same fix should be made in corefx clone of the |
Maybe we can change to a new algorithm for CoreClr. The current algorithm is really bad on many fronts. XorShift (possibly strengthened as XorShift+) is faster, has better random numbers and a smaller state size. On the other hand if a program relies on So maybe the right solution is to add a |
I would like to grab this one. The issue originally started to correct the numbers in the existing generator. However, I really like the XorShift+ and it is well known for fast computation. |
Just correct the numbers. There are many different random number generators. They should be provided as independent libraries - there are actually quite a few of them on https://www.nuget.org/packages?q=Random. |
If compatibility is broken anyway it would be a good time to use a new algorithm altogether. XorShift+ is far superior to the old one. It is easy to implement. |
True. I agree that it would be a breaking change for the people relying on static IEnumerable<int> Generate(int seed, int count)
{
var gen = new Random(seed);
return Enumerable.Range(0, count)
.Select(_ => gen.Next());
}
[Fact]
void Test()
{
var expected = new int[] { 1434747710, 302596119, 269548474, 1122627734, 361709742 };
var actual = Generate(42, 5);
actual.ShouldBe(expected);
} So, changing the numbers inside current Having realized it would be a breaking change in the Random number generation logic, @jkotas do you still think we should just change the numbers whereas we can replace the algorithm with a cool and faster one? |
xorshift has different properties and problems. https://en.wikipedia.org/wiki/Xorshift lists some of them. The new algorithm would need to be same or better in all dimensions compared to the current one - cool and faster is not sufficient. Is there analysis that shows that (some variant of) xorshift is same or better in all dimensions compared to the current algorithm? Have class libraries for other systems/languages picked xorshift as the default random number generator?
BTW: We do take compatibility pretty seriously even in .NET Core. However, we are not aiming for full bug-for-bug compatibility like in full .NET Framework. Improvements of random number generator are compatible, but they are not bug-for-bug compatible. |
XorShift+ variant in the same page overcomes the limitations of the plain XorShift. As for the comparison with the current one, I will get back to you when I get some data. |
There is a PRNG comparison at http://xoroshiro.di.unimi.it/. It doesn't include the one currently used in System.Random though. |
Whenever I researched XorShift I only found claims of quality. For example http://stats.stackexchange.com/questions/40680/is-xorshift-rng-good-enough-for-monte-carlo-approaches-if-not-what-alternatives links to http://xoroshiro.di.unimi.it/. This seems to be a pretty comprehensive work. XorShift is so fast that one can easily spend some perf to make the quality even better and to remove doubts. For example, XorShift+ adds two consecutive values. I can see a case for combining even more values into one. For example, run two parallel XorShift+ generators internally and xor their output. I'd be surprised if any meaningful non-randomness could be found there. (It always can be found in non-secure RNG's by creating a test designed to specifically target a given generator. This is unavoidable and not a problem.)
Seems thorough.
These people probably did not make that decision lightly. Seems like a good endorsement. I have not heard about
Sounds good, but they say in the code:
This seems to kill that generator. I don't understand how they can recommend it. XorShift+ does not suffer from biased bits. The authors of My advice is implementing It's better than the old algorithm in the dimensions: Speed, quality, state size. I believe the existing algorithm is quite bad in all of them. Library designers tend to make terrible RNG choices. The Mersenne twister is common yet terrible. It's slow, has quality issues and has 2.5KB state size! I do not understand what leads people to use it. (http://cs.stackexchange.com/questions/50059/why-is-the-mersenne-twister-regarded-as-good) Here, we have a chance to make a very good choice. |
Here is what I am planning to do (or, doing):
I hope once I have the results, we will be able to discuss it further. |
I have finished implementing XorShift128+ and XorShiRo128+. Generated random bytes using
Note: Do not take the |
What XorShift variant is this? When I researched and implemented mine 10 years ago I picked this variant:
I also have code to generate bytes in bulk:
Back then it ran at 800MB/sec on a much slower CPU. I spend a lot of time optimizing this. It sohuld be a good starting point. I chose to clock the generator a few times when seeding to be more robust against bad seeds:
|
It is XorShift128+ variant. You will find its reference implementation, along with XorShiRo128+ variant (which is even faster) at http://xoroshiro.di.unimi.it/ |
xoroshiro seems unsafe to me. Is this not a concern? |
@GSPP I am not quite sure which part is unsafe. If you can explain a bit or provide a simple test demonstrating the safety issue, it would help a lot. Or, is the algorithm inherently unsafe? I didn't get the idea though from reading the papers and articles. |
The source code says:
So the lowest bit might not be of high quality. |
@GSPP I see your point. However, if you look at the signature of the publicly accessible method of |
This topic is being discussed in https://github.com/dotnet/corefx/issues/12746 |
The discussion on this can continue in dotnet/corefx#12746. Even though the build-in random algorithm is not perfect, changing it would very likely cause many breakages accross the ecosystem - it is unlikely we can accept changes in it. |
System.Random class algorithm bug is reported about 5 years ago at Connect site.
and bugfix is postponed by concerning existing app compatibility issue.
https://connect.microsoft.com/VisualStudio/feedback/details/634761/system-random-serious-bug
Current MSDN document explicitly stated at "Notes to Callers" sections
https://msdn.microsoft.com/en-us/library/system.random(v=vs.110).aspx
This statement seems to be added March 2011 (by .NET 3.5 document Change History)
and abount 5 years have passed since then.
Is there any plan to fix this issue? (or add new Random provider/interface)
The text was updated successfully, but these errors were encountered: