Passing large or complex data structures to threads
Joseph Rushton Wakeling
joseph.wakeling at webdrake.net
Fri May 31 07:43:34 PDT 2013
On 05/27/2013 02:08 PM, Joseph Rushton Wakeling wrote:
> On 05/26/2013 05:59 PM, Ali Çehreli wrote:
>> On 05/26/2013 05:38 AM, Simen Kjaeraas wrote:
>>
>>
>>> Tuple!(size_t, size_t)[][] data = createData();
>>> immutable dataImm = assumeUnique(data);
>>> data = null; // Simply to ensure no mutable references exist.
>>
>> The last line is not needed. assumeUnique already does that. :)
>
> That's fantastic, thank you both very much. Does that also work for arbitrary
> data structures (e.g. also associative arrays, complex structs/classes etc.)?
>
> Related question -- assume that I now want to store that immutable data inside a
> broader storage class, but I want that storage class to be agnostic as to
> whether the data is immutable, const or mutable.
I thought I'd mention the practical solution I eventually came to here, which is
a combination of things learned from this discussion and the subsequent one on
duplicating a multidimensional array.
I first of all had a go at tweaking the templatization of my storage classes, in
line with some of the tricks Ali suggested for the multidimensional duplication
function. In this case a storage class that had this form (cutting out
extraneous details):
class SeedSIS(T)
{
T[] immune;
T[] susceptible;
T[] recover;
Link!T[][] network;
this(T[] imm, T[] sus, T[] rec, Link!T[][] net)
{
immune = imm;
susceptible = sus;
recover = rec;
network = net;
}
}
... was tweaked to this form:
class SeedSIS(T, Network : L[][], L)
{
T[] immune;
T[] susceptible;
T[] recover;
Network network;
this(T[] imm, T[] sus, T[] rec, Network net)
{
immune = imm;
susceptible = sus;
recover = rec;
network = net;
}
}
... which enabled the network input to be mutable or immutable. With a bit more
effort, I guess it would be possible to tweak the other inputs to extend that
option to them; it could be useful as a guarantee related to what bits of the
Seed class will change.
However, I found that in practice this reworked design (which involved reworking
lots of templates elsewhere as well) led to slowdown in some crucial bits of the
code. So, instead I found an alternative solution following Ali's guidance
about using to!()() as a copying device, which was to pass the immutable network
to threads, and then take a mutable local copy via,
mutableNetwork = to!(Link!T[][])(immutableNetwork);
... which could then be used with the original templates.
More information about the Digitalmars-d-learn
mailing list