Re: Question on shared memory concurrency
On Monday, 4 March 2024 at 03:42:48 UTC, Richard (Rikki) Andrew Cattermole wrote: A way to do this without spawning threads manually: ... Thank you! Of course, a thread dispatch per atomic increment is going to be s.l.o.w., so not surprising you had to trim the iterations. Bug I still hope to be able to share memory between spawned threads, and if it isn't a shared ref of a shared variable, then what would it be? Do I have to use the memory allocator?
Re: Question on shared memory concurrency
On Monday, 4 March 2024 at 16:02:50 UTC, Andy Valencia wrote: On Monday, 4 March 2024 at 03:42:48 UTC, Richard (Rikki) Andrew Cattermole wrote: A way to do this without spawning threads manually: ... Thank you! Of course, a thread dispatch per atomic increment is going to be s.l.o.w., so not surprising you had to trim the iterations. Bug I still hope to be able to share memory between spawned threads, and if it isn't a shared ref of a shared variable, then what would it be? Do I have to use the memory allocator? There is `__gshared` type qualifier, but unlike plain `shared` it is up to you to ensure valid concurrency access as stated in the docs. https://dlang.org/spec/const3.html#shared_global
Re: Question on shared memory concurrency
On Monday, 4 March 2024 at 16:02:50 UTC, Andy Valencia wrote: On Monday, 4 March 2024 at 03:42:48 UTC, Richard (Rikki) Andrew Cattermole wrote: ... I still hope to be able to share memory between spawned threads, and if it isn't a shared ref of a shared variable, then what would it be? Do I have to use the memory allocator? For any other newbie dlang voyagers, here's a version which works as expected using the system memory allocator. On my little i7 I get 1.48 secs wallclock with 5.26 CPU seconds. import core.atomic : atomicFetchAdd; import std.concurrency : spawn; import core.time : msecs; import core.thread : Thread; import core.memory : GC; const uint NSWEPT = 100_000_000; const uint NCPU = 4; void doadd(shared uint *buf) { for (uint count = 0; count < NSWEPT/NCPU; ++count) { atomicFetchAdd(buf[0], 1); } } void main() { shared uint *buf = cast(shared uint *)GC.calloc(uint.sizeof * 1, GC.BlkAttr.NO_SCAN); for (uint x = 0; x < NCPU-1; ++x) { spawn(&doadd, buf); } doadd(buf); while (buf[0] != NSWEPT) { Thread.sleep(1.msecs); } }
Testing membership in associative array
I am trying to create a function that tests membership in nested associative array, however the function I create below, only accepts keys of the same type and if given keys of different types it does not compile, help would be appreciated. This is a example of what Im talking about. ```d import std.stdio; void main() { int[int][int] aa1; aa1[1][2] = 3; writeln(contains(aa1, 1, 2)); //returns true as expected int[int][string] aa2; aa2["1"][2] = 3; writeln(contains(aa2, "1", 2)); //does not compile because of this line } bool contains(M, K...)(M map, K keys) { foreach(key; keys) if(key in map) return contains(map[key], keys[1 .. $]); else return false; return true; } ```
Re: Need help with Windows linkage ( DMD using ImportC)
On Monday, 4 March 2024 at 21:21:20 UTC, Carl Sturtivant wrote: ``` blah.obj: error LNK2019: unresolved external symbol _mul128 referenced in function MultiplyExtract128 blah.obj: error LNK2019: unresolved external symbol __shiftright128 referenced in function MultiplyExtract128 blah.obj: error LNK2019: unresolved external symbol _umul128 referenced in function UnsignedMultiplyExtract128 blah.obj: error LNK2019: unresolved external symbol __stosb referenced in function RtlSecureZeroMemory blah.obj: error LNK2019: unresolved external symbol __readgsqword referenced in function NtCurrentTeb blah.obj: error LNK2019: unresolved external symbol __imp_MapViewOfFileNuma2 referenced in function MapViewOfFile2 blah.obj: error LNK2019: unresolved external symbol __imp_CharUpperW referenced in function ua_CharUpperW ``` I forced linkage of these unused symbols as follows, but it would be nice to have a clean way to proceed. ```D extern(C) { int _InterlockedExchangeAdd(int* Addend, int Value) { return 0; }; long _InterlockedExchangeAdd64(long* Addend, long Value) { return 0; } void _mul128() {}; void __shiftright128() {}; void _umul128() {}; void __stosb() {}; void __readgsqword() {}; void __imp_MapViewOfFileNuma2() {}; void __imp_CharUpperW() {}; } ``` I got the D signatures of the first two so as to generate the correct linkage by using ImportC to translate the inclusion of `Windows.h` into a .di file, and searching.
Re: Testing membership in associative array
On Monday, 4 March 2024 at 23:49:46 UTC, Lettever wrote: [ ... ] ```d // A template constraint is added to ensure we may always index into `keys`, // in addition to being a sanity check. bool contains(M, K...)(M map, K keys) if (K.length > 0) { static if (K.length == 1) return (keys[0] in map) !is null; else return contains(map[keys[0]], keys[1 .. $]); } ``` One might also be interested in adding a static assert or template constraint ensuring the number of keys passed are less than or equal to the nested-ness of the associated array.
Re: Testing membership in associative array
My sincerest apologies, my initial solution is flawed due to a foolish oversight. The below version works. ```d bool contains(M, K...)(M map, K keys) if (K.length > 0) { static if (K.length == 1) return (keys[0] in map) !is null; else return (keys[0] in map) !is null && contains(map[keys[0]], keys[1 .. $]); } ```