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