HPCE / hpce-2017-cw6

2 stars 17 forks source link

Possible to have two different workload (RNG) instances at the same time? #30

Closed adamsolomou closed 6 years ago

adamsolomou commented 6 years ago

If I've understood correctly workload_Next() deletes the current RNG instance (if it exists) in order to then create a new/distinct one using workload_Create(). So my question is whether is actually possible to have two (or more) different RNGs instances (workloads) active at the same time? (given that we can't modify the workload code and since workload_Next() cannot be called in parallel with itself).

So for example if I do something like this:

unif01_Gen *gen_1=workload_Create(); 
std::string name_1=workload_Name(gen_1);

workload_Next();

unif01_Gen *gen_2=workload_Create(); 
std::string name_2=workload_Name(gen_2);

Does that mean that gen_1 instance can no longer be used? And if that's the case is there a way to overtake this?

natoucs commented 6 years ago

I am not sure I can answer your question directly and probably David Thomas will, but I can tell you something that might help doing what you are trying to do. Try using workload_Clone(); . It allows you to get many different instances and use them at the same time :)

adamsolomou commented 6 years ago

Thanks for the info @natoucs . I'm already using workload_Clone() but that returns a copy of an RNG instance in the same state right? So in that case gen_1 and gen_2 would behave in the same way (i.e. they will produce the same sequence of numbers), they are just two independent instances (please correct me if I'm wrong). What I'm interested is if I can have two different RNG active at the same time, which won't be in the same state and would generate a different sequence of numbers. I hope that makes sense :)

m8pple commented 6 years ago

The code given by @adamosSol is fine from a concurrency point of view - it is only that workload_Next cannot be called in parallel with itself, so once you have called it and got multiple different generators then you are free to use those generators in parallel with each other.

So using the original example, we could safely make it parallel using:

unif01_Gen *gen_1=workload_Create(); 
std::string name_1=workload_Name(gen_1);

workload_Next();

unif01_Gen *gen_2=workload_Create(); 
std::string name_2=workload_Name(gen_2);

tbb::parallel_invoke(
   [&](){   do_something_with(gen_1);  },
   [&](){   do_something_else_with(gen_2);  }
);

What you can't do is something like:

tbb::parallel_invoke(
   [&](){
       workload_Next();
       unif01_Gen *gen_1=workload_Create();
       do_something_with(gen_1);
   },
   [&](){
       workload_Next();
       unif01_Gen *gen_2=workload_Create();
       do_something_else_with(gen_2);
   }
);

as here the two calls to workload_Next would happen in parallel.

adamsolomou commented 6 years ago

Thanks for the clarification!