www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - New to D - playing with Thread and false Sharing

reply "tony288" <tony tony.tony> writes:
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
next sibling parent reply "Dejan Lekic" <dejan.lekic gmail.com> writes:
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
next sibling parent reply "tony288" <tony tony.tony> writes:
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
next sibling parent reply "Nicholas Wilson" <iamthewilsonator hotmail.com> writes:
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:
 [...]
Thanks, I changed the code and the previous one was already using shared. import std.stdio; import core.time; import core.thread; [...]
Keep in mind java may be using green threads as opposed to kernel threads. The equivalent in D is a Fiber.
Aug 20 2015
parent Russel Winder via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> writes:
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
prev sibling parent Russel Winder via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> writes:
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
prev sibling parent reply Rikki Cattermole <alphaglosined gmail.com> writes:
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
parent "John Colvin" <john.loughran.colvin gmail.com> writes:
On Friday, 21 August 2015 at 02:44:50 UTC, Rikki Cattermole wrote:
 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.
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.
Aug 21 2015
prev sibling parent reply "Kagamin" <spam here.lot> writes:
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
parent "tony288" <tony tony.tony> writes:
On Friday, 21 August 2015 at 12:45:52 UTC, Kagamin wrote:
 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?
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?
Aug 21 2015