Re: Question on shared memory concurrency

2024-03-04 Thread Andy Valencia via Digitalmars-d-learn
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

2024-03-04 Thread evilrat via Digitalmars-d-learn

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

2024-03-04 Thread Andy Valencia via Digitalmars-d-learn

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

2024-03-04 Thread Lettever via Digitalmars-d-learn
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)

2024-03-04 Thread Carl Sturtivant via Digitalmars-d-learn

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

2024-03-04 Thread Profunctor via Digitalmars-d-learn

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

2024-03-04 Thread Profunctor via Digitalmars-d-learn
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 .. $]);

}
```