digitalmars.D.learn - New to D - playing with Thread and false Sharing
- tony288 (69/69) Aug 20 2015 Hi,
- Dejan Lekic (3/3) Aug 20 2015 Keep in mind that in D everything is thread-local by default! :)
- tony288 (61/64) Aug 20 2015 Thanks, I changed the code and the previous one was already using
- Nicholas Wilson (4/12) Aug 20 2015 Keep in mind java may be using green threads as opposed to kernel
- Russel Winder via Digitalmars-d-learn (19/23) Aug 21 2015 [=E2=80=A6]
- Russel Winder via Digitalmars-d-learn (21/27) Aug 21 2015 [=E2=80=A6]
- Rikki Cattermole (2/5) Aug 20 2015 Note: shared is __gshared but with mutex's added.
- John Colvin (7/14) Aug 21 2015 Nope. shared is a type modifier that signifies the data is not
- Kagamin (2/5) Aug 21 2015 Should it be different?
- tony288 (21/26) Aug 21 2015 Hi
Hi, I have been playing for a short time with D. I wanted to play with Thread, which I believe is lower level than concurrency and parallelism library (might be wrong here ?) . I was also learning and reading about false sharing - multiple thread => same cacheline. And I decided to play with both to 1 understand more D and see the results of false sharing. So I wrong some code. But it seems the time to process a shared struct & shared long is always the same. Regardless of adding paddings. My thoughts is that as I'm new to D. That it can only be my fault and not doing things correctly. I doubt the compiler etc.. adds etc padding? If you have any code to show it, it would be really great. But this is what I have done : I found this article http://mechanical-sympathy.blogspot.co.uk/2011/08/false-sharing-java-7.html and tried to emulate this. In java I do get the same result as them and can understand the code. But curious in D i get completely different results. import std.stdio; import core.time; import core.thread; void main() { writeln(PaddingStruct.sizeof); MonoTime before = MonoTime.currTime; runTest(); MonoTime after = MonoTime.currTime; Duration timeElapsed = after - before; writeln("Duration is " , timeElapsed) ; } private static void runTest() { Thread[] threads = new Thread[4]; for (int i = 0; i < threads.length; i++) threads[i] = new FalseSharing(i);//putting a new thread in the array foreach(Thread t ; threads){//starts all threads t.start(); } foreach(Thread t; threads){ t.join(); } } class FalseSharing : Thread { private static PaddingStruct[] longs = new PaddingStruct[4]; private const int threadIndex; this(const int index) { threadIndex = index; PaddingStruct a; longs[threadIndex] = a; super(&run); } void run() { long i = 500L * 1000L * 1000L; writeln(" threadindex is -> " , threadIndex); writeln(" i is -> " , i); while (0 != --i){longs[threadIndex].value = i;} writeln("threaded ",threadIndex," ended so a=1 -> is it? ", longs[threadIndex].value); } } struct PaddingStruct { static shared long value = 0L; //shared across multiple thread //long p1,p2,p3,p4,p1a;//padding. }
Aug 20 2015
Keep in mind that in D everything is thread-local by default! :) For shared resources use __gshared or shared (although I do not know for sure whether shared works or not).
Aug 20 2015
On Thursday, 20 August 2015 at 15:37:35 UTC, Dejan Lekic wrote:Keep in mind that in D everything is thread-local by default! :) For shared resources use __gshared or shared (although I do not know for sure whether shared works or not).Thanks, I changed the code and the previous one was already using shared. import std.stdio; import core.time; import core.thread; void main() { MonoTime before = MonoTime.currTime; runTest(); MonoTime after = MonoTime.currTime; Duration timeElapsed = after - before; writeln("Duration is " , timeElapsed) ; } private static void runTest() { Thread[] threads = new Thread[4]; FalseSharing[] fs = new FalseSharing[4]; for (int i = 0; i < threads.length; i++){ FalseSharing fsx = new FalseSharing(i); fs[i] = fsx; threads[i] = fsx; } foreach(Thread t ; threads){//starts all threads t.start(); } foreach(Thread t; threads){ t.join(); } } static PaddingClass[] longs = new PaddingClass[4]; class FalseSharing : Thread { private const int threadIndex; this(const int index) { threadIndex = index; longs[threadIndex] = new PaddingClass(); super(&run); } void run() { long max = 1000L * 100L * 100L * 10L; for(long i=1; i<=max ; i++){longs[threadIndex].value = i;} } } public static shared class PaddingClass { public double p1,p2,p3,p4,p5,p6;//padding. public shared long value = 0L; //shared across multiple thread } So what I see, D ( of course and expected) using more or less the same syntax as java. Behaves very differently. Which I mean padding or not, D behaves slower than Java with padding by a long way. Now what I would like to know, how would I make this code more efficient? Which is basically the aim I'm trying to achieve. Any pointers would be really help full. Should I use concurrency/parallelism etc..? Thanks
Aug 20 2015
On Thursday, 20 August 2015 at 20:01:58 UTC, tony288 wrote:On Thursday, 20 August 2015 at 15:37:35 UTC, Dejan Lekic wrote:Keep in mind java may be using green threads as opposed to kernel threads. The equivalent in D is a Fiber.[...]Thanks, I changed the code and the previous one was already using shared. import std.stdio; import core.time; import core.thread; [...]
Aug 20 2015
On Fri, 2015-08-21 at 01:22 +0000, Nicholas Wilson via Digitalmars-d -learn wrote:=20[=E2=80=A6]Keep in mind java may be using green threads as opposed to kernel=20 threads. The equivalent in D is a Fiber.I believe Java itself hasn't used green threads in an awful long time: Threads are mapped to kernel threads. As you say the "lightweight threads" (aka "green threads",=E2=80=A6) has recently (!) been reinvented under the name fibers. One of the Java market leaders for this is Quasar, another is GPars. =20 --=20 Russel. =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder ekiga.n= et 41 Buckmaster Road m: +44 7770 465 077 xmpp: russel winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
Aug 21 2015
On Thu, 2015-08-20 at 20:01 +0000, tony288 via Digitalmars-d-learn wrote:=20[=E2=80=A6]Now what I would like to know, how would I make this code more=20 efficient? Which is basically the aim I'm trying to achieve. =20 Any pointers would be really help full. Should I use=20 concurrency/parallelism etc..?I have found very, very few codes (in many different language, including Java) that were not massively improved by removal of all explicit thread (and fiber) usage. Threads and fibers are, and should be, infrastructure for application level APIs. If a language doesn't have the abstractions then it is deficient and should gain them quickly or not be used. I observe that the only programs that need to explicitly use threads and fibers are the ones that must explicitly manage heap and stack. --=20 Russel. =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder ekiga.n= et 41 Buckmaster Road m: +44 7770 465 077 xmpp: russel winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
Aug 21 2015
On 8/21/2015 3:37 AM, Dejan Lekic wrote:Keep in mind that in D everything is thread-local by default! :) For shared resources use __gshared or shared (although I do not know for sure whether shared works or not).Note: shared is __gshared but with mutex's added.
Aug 20 2015
On Friday, 21 August 2015 at 02:44:50 UTC, Rikki Cattermole wrote:On 8/21/2015 3:37 AM, Dejan Lekic wrote:Nope. shared is a type modifier that signifies the data is not guaranteed to be thread-local (and as such can be passed between threads). It generates no extra code and has no special ordering or atomicity guarantees. The way I look at it, shared is roughly equivalent to normal C/C++ variables.Keep in mind that in D everything is thread-local by default! :) For shared resources use __gshared or shared (although I do not know for sure whether shared works or not).Note: shared is __gshared but with mutex's added.
Aug 21 2015
On Thursday, 20 August 2015 at 15:31:13 UTC, tony288 wrote:So I wrong some code. But it seems the time to process a shared struct & shared long is always the same. Regardless of adding paddings.Should it be different?
Aug 21 2015
On Friday, 21 August 2015 at 12:45:52 UTC, Kagamin wrote:On Thursday, 20 August 2015 at 15:31:13 UTC, tony288 wrote:Hi all thanks, I guess there is a subtopic going on now. But I rewrote the code so that D & Java looks fairly similar. First my mistake is I divided Nanosecond with too many zeros to get ms and hence Java seemed far superior and hence my frustration. That corrected D looked better - but I feel it is a bad comparison anyways different language etc... So won't say 1 is faster than the other. What I do find interesting is really now going back to the padding and false sharing. If I take the code here http://mechanical-sympathy.blogspot.co.uk/2011/07/false-sharing.html edit it as I mentioned above. The extra Padding Does affect quite a bit Java. However with D, not so much. So was curious if something is happening in the compiler. I remember I read a thread on this community about alignAllocate .... but couldn't really follow the post. So back to shared.. If Shared should be considered a "normal" accessible my multiple threads. Should I put this in somekind of lock/mutex/semaphore?So I wrong some code. But it seems the time to process a shared struct & shared long is always the same. Regardless of adding paddings.Should it be different?
Aug 21 2015