Posts: 32
Threads: 4
Joined: Jul 2013
Thanks: 0
Given 2 thank(s) in 1 post(s)
Hi.
I can see you are using a very specific random function, that is not thread-safe, and maybe heavy to load.
I didn't read the whole class, just the comments, and they are frightening.
Question are :
1. may I instanciate one where and when I want ?
2. may I instanciate a static one ?
If this is touchy (aka I cannot instantiate one where I want), I'll suggest to refactor it's usage, for example through something like a std::map<thread,MTRand> that would be accessed statically. What would you think about it ?
Basically : it would not be coder-friendly to have to think twice for getting a random number.
But maybe it's all in my head.
Thanks
Posts: 6,485
Threads: 176
Joined: Jan 2012
Thanks: 131
Given 1075 thank(s) in 852 post(s)
Basically, you are right.
1, Yes, you can, but as you've already noted, it's quite some heavy-lifting to do so. If you can work around it, go around it.
2, Yes, you can, theoretically, as long as you can guarantee a single thread accessing it at a time (locking etc).
For these reasons, there is an MTRand instance within cWorld that is to be used in the Tick thread exclusively and has some accessor functions in cWorld directly (GetTickRandomNumber() ). If you can guarantee that your function runs only in the tick thread, you can use it.
Usually, we don't even need such a big random function; if you just need a reasonably random number, you could use the cNoise IntNoiseNDInt() functions, feeding them some clock-based values, such as the number of ticks elapsed in the world, world seed, and probably some kind of a static counter.
Another question is, how does MTRand fail when used in multiple threads? Does the failure produce crashes, or does it simply just somewhat degrade the resulting random numbers? If the latter, I'd personally go with abusing that and simply using it from multiple threads.
Posts: 6,485
Threads: 176
Joined: Jan 2012
Thanks: 131
Given 1075 thank(s) in 852 post(s)
We don't have a thread-local storage, so you'd need to implement one - not a trivial task, considering all the platforms we support. Also, you need some kind of management for when a new thread is created or another one ends, to create and destroy the objects.
Next, you have performance issues - will it be fast enough to be called as many times as required? And if the result contains any synchronization primitive, how much will it be susceptible to deadlocks?
Two easier solutions:
- let the caller provide a random number; the caller knows which thread it's on and can therefore decide on TickRand or a different generator
- use a different generator. I still think using cNoise would be the best bet here.