April 28, 2019
On 28/04/2019 8:34 PM, Dibyendu Majumdar wrote:
> I have to understand the model. Suppose some mutable data is passed around between threads. I don't really know as I haven't read this in detail - but my question is this: is there a cost to accessing data across threads?

Same cost compared to C.
April 28, 2019
On Sun, 2019-04-28 at 08:34 +0000, Dibyendu Majumdar via Digitalmars-d wrote:
> […]
> 
> I have to understand the model. Suppose some mutable data is passed around between threads. I don't really know as I haven't read this in detail - but my question is this: is there a cost to accessing data across threads?

It depends what you mean by passing here: passing by value, i.e. making a copy of the value and losing all reference to the original, can be fairly overhead free; passing by reference always imposes some sort of overhead. This is for all programming languages.

> As in C or C++ I would expect the cost to be zero unless marked volatile.

I think you need to offer some examples here. As far as I am aware C++ has overhead for dealing with mutable data between threads: unique_ptr and shared_ptr are not zero cost.

Arguably Rust gets closest to zero cost by having a move by default and borrow system that is checked at compile time. (For heap values referenced using an Arc instance there is a runtime cost of type and accessibility checking.) C++ hasn't quite got there as yet.

> I admit I don't understand the model of memory access in D. It seems that like Go, D is attempting to push a message passing model - that's what I meant by 'imposing a model'.

Message passing is the One True Way™ of handling data in a parallel or concurrent system – obviously safety requires pass by value rather than pass by reference. Go has this right in the language except that it allows passing pointers. Rust mostly has this right in the language with the futures package (or equivalent in gtk-rs). D doesn't really have this right but is well on the way. C++17 I haven't investigated properly, but C++14 was far, far, far from doing the right thing, so I doubt C++17 has it right.

So you meant memory model and not programming model. C++, D, Rust, Go all have memory models, as Java, Kotlin, etc. have. Indeed a programming language that has concurrency and parallelism features in the language or standard library that doesn't have a memory model has so many "undefined behaviours" as to be nigh on useless.

-- 
Russel.
===========================================
Dr Russel Winder      t: +44 20 7585 2200
41 Buckmaster Road    m: +44 7770 465 077
London SW11 1EN, UK   w: www.russel.org.uk



April 28, 2019
On Sunday, 28 April 2019 at 08:47:06 UTC, rikki cattermole wrote:
> On 28/04/2019 8:34 PM, Dibyendu Majumdar wrote:
>> I have to understand the model. Suppose some mutable data is passed around between threads. I don't really know as I haven't read this in detail - but my question is this: is there a cost to accessing data across threads?
>
> Same cost compared to C.

Is there a document that describes the rules regarding concurrent memory access, such as the Java Memory Model or C++ Memory Model (https://en.cppreference.com/w/cpp/language/memory_model)?

Suppose some data needs to be shared between threads, and it is not global data. Does it need to be marked 'shared'? Reading Andrei's doc I got the impression that the 'shared' mark has a cost.

Thanks
April 28, 2019
On Sunday, 28 April 2019 at 09:03:00 UTC, Russel Winder wrote:

> So you meant memory model and not programming model. C++, D, Rust, Go all have memory models, as Java, Kotlin, etc. have. Indeed a programming language that has concurrency and parallelism features in the language or standard library that doesn't have a memory model has so many "undefined behaviours" as to be nigh on useless.

I meant both. By programming model I meant the idea that a language pushes for certain type of programming. Go is a good example. It cannot be called a systems language (I believe it no longer is).

April 28, 2019
On Sunday, 28 April 2019 at 09:03:00 UTC, Russel Winder wrote:
> On Sun, 2019-04-28 at 08:34 +0000, Dibyendu Majumdar via Digitalmars-d wrote:
>> […]
>> 
>> I have to understand the model. Suppose some mutable data is passed around between threads. I don't really know as I haven't read this in detail - but my question is this: is there a cost to accessing data across threads?
>
> It depends what you mean by passing here: passing by value, i.e. making a copy of the value and losing all reference to the original, can be fairly overhead free; passing by reference always imposes some sort of overhead. This is for all programming languages.
>
>> As in C or C++ I would expect the cost to be zero unless marked volatile.
>
> I think you need to offer some examples here. As far as I am aware C++ has overhead for dealing with mutable data between threads: unique_ptr and shared_ptr are not zero cost.
>


I wasn't talking about the cost of passing data, more about the cost of operations with this.

Say we have something like this.


SomeFunc(data)
    various ops with data
    return data

There should not be any extra overhead in the 'ops' part above. In C++ if data was marked volatile, then there would be an impact, but not otherwise, apart from the standard optimisation rules to do with data escaping, or aliasing something.
April 28, 2019
On 28/04/2019 9:05 PM, Dibyendu Majumdar wrote:
> On Sunday, 28 April 2019 at 08:47:06 UTC, rikki cattermole wrote:
>> On 28/04/2019 8:34 PM, Dibyendu Majumdar wrote:
>>> I have to understand the model. Suppose some mutable data is passed around between threads. I don't really know as I haven't read this in detail - but my question is this: is there a cost to accessing data across threads?
>>
>> Same cost compared to C.
> 
> Is there a document that describes the rules regarding concurrent memory access, such as the Java Memory Model or C++ Memory Model (https://en.cppreference.com/w/cpp/language/memory_model)?
> 
> Suppose some data needs to be shared between threads, and it is not global data. Does it need to be marked 'shared'? Reading Andrei's doc I got the impression that the 'shared' mark has a cost.
> 
> Thanks

shared does nothing.
There is strong desire to remove it, most people cast it away since its just a pain in the type system (ignoring its behavior of __gshared for globals).

I think you're over thinking it.

Yes you do need to use some form of memory synchronization strategy.
No, the language does not force it.
Yes the standard library does offer some solutions to this end.
No, the language is by default unsafe and you're free to do anything you want including BSOD your computer. This is what native languages offer you.
April 28, 2019
On Sunday, 28 April 2019 at 09:24:52 UTC, rikki cattermole wrote:
> shared does nothing.
> There is strong desire to remove it, most people cast it away since its just a pain in the type system (ignoring its behavior of __gshared for globals).
>
> I think you're over thinking it.
>
> Yes you do need to use some form of memory synchronization strategy.
> No, the language does not force it.
> Yes the standard library does offer some solutions to this end.
> No, the language is by default unsafe and you're free to do anything you want including BSOD your computer. This is what native languages offer you.

Okay that's good )
May 17, 2019
On Sunday, 28 April 2019 at 08:27:31 UTC, Dibyendu Majumdar wrote:
> On Sunday, 28 April 2019 at 01:22:32 UTC, Heromyth wrote:
>> On Saturday, 27 April 2019 at 14:15:01 UTC, Dibyendu Majumdar wrote:
>>> Java programmers have benefited hugely from Doug Lea's work (http://gee.cs.oswego.edu/dl/concurrency-interest/index.html). I was wondering if D's library has anything equivalent. If not, I am interested in porting Doug Lea's library from Java to D; I think the license allows this, but I will check with Doug Lea.
>>
>> We have done somthing about this. See here:
>>
>> Source: https://github.com/huntlabs/hunt/tree/master/source/hunt/concurrency
>> Examples: https://github.com/huntlabs/hunt/tree/master/examples/UnitTest/source/test
>>
>> Current stage: We are trying to port the CompletableFuture.
>
> Nice. Some questions:
>
> Have you based this on the Java8 version from Doug Lea's repository? Presumably this isn't a port of Oracle's version?
> The concurrent collections aren't ported, am I right?
>
> BTW Doug Lea's copyright notice should be retained in the sources if you have ported his code.

The most copyright notices are retained. All the code are porting from OpenJDK 8/11.

The porting of CompletableFuture done. The 20 examples from [1] are passed, see [2].

The next step is make CompletableFuture support value type like int, string etc.

[1] https://mahmoudanouti.wordpress.com/2018/01/26/20-examples-of-using-javas-completablefuture/
[2] https://github.com/huntlabs/hunt/blob/master/examples/UnitTest/source/test/CompletableFutureTest.d
May 17, 2019
On Friday, 17 May 2019 at 06:36:05 UTC, Heromyth wrote:

> The most copyright notices are retained. All the code are porting from OpenJDK 8/11.

I have wondered what the copyright requirements are in porting a library from one language to another. I notice that for String.java

http://www.docjar.com/html/api/java/lang/String.java.html

to
String.d,

https://github.com/huntlabs/hunt/blob/master/source/hunt/String.d

you have removed the copyright notices of Oracle while trying to maintain some amount of their API. And also retaining their comments, for instance:

/**
 * The {@code String} class represents character strings. All
 * string literals in Java programs, such as {@code "abc"}, are
 * implemented as instances of this class.
 * <p>
 * Strings are constant; their values cannot be changed after they
 * are created. String buffers support mutable strings.
 * Because String objects are immutable they can be shared. For example:

In asking about a port like this, people have claimed that the Oracle copyright should be in your source files.

May 17, 2019
On Sunday, 28 April 2019 at 09:03:00 UTC, Russel Winder wrote:
> I think you need to offer some examples here. As far as I am aware C++ has overhead for dealing with mutable data between threads: unique_ptr and shared_ptr are not zero cost.

A bit late reply, but unique_ptr is near zero cost, however, neither are thread safe.
For that you need to wrap the smart-pointer like std::atomic<std::shared_ptr<T>> (C++20).

Anyway, I'd argue that irrespective of language you might as well consider implementing your own shared store using CAS instructions and avoid locking altogether. If it fits what you want to do.

In D's typesystem that means that only the encapsulating datastructure would be shared and all the nodes would be nonshared (you acquire them using CAS).