Thread overview | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
|
August 20, 2015 New to D - playing with Thread and false Sharing | ||||
---|---|---|---|---|
| ||||
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. } |
August 20, 2015 Re: New to D - playing with Thread and false Sharing | ||||
---|---|---|---|---|
| ||||
Posted in reply to tony288 | 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). |
August 20, 2015 Re: New to D - playing with Thread and false Sharing | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dejan Lekic | 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
|
August 21, 2015 Re: New to D - playing with Thread and false Sharing | ||||
---|---|---|---|---|
| ||||
Posted in reply to tony288 | 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.
|
August 21, 2015 Re: New to D - playing with Thread and false Sharing | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dejan Lekic | 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.
|
August 21, 2015 Re: New to D - playing with Thread and false Sharing | ||||
---|---|---|---|---|
| ||||
Posted in reply to Rikki Cattermole | 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.
|
August 21, 2015 Re: New to D - playing with Thread and false Sharing | ||||
---|---|---|---|---|
| ||||
Posted in reply to tony288 | 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?
|
August 21, 2015 Re: New to D - playing with Thread and false Sharing | ||||
---|---|---|---|---|
| ||||
Posted in reply to Kagamin | 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? |
August 22, 2015 Re: New to D - playing with Thread and false Sharing | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nicholas Wilson Attachments:
| On Fri, 2015-08-21 at 01:22 +0000, Nicholas Wilson via Digitalmars-d -learn wrote: > […] > Keep in mind java may be using green threads as opposed to kernel > 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",…) has recently (!) been reinvented under the name fibers. One of the Java market leaders for this is Quasar, another is GPars. -- Russel. ============================================================================= Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder@ekiga.net 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 |
August 22, 2015 Re: New to D - playing with Thread and false Sharing | ||||
---|---|---|---|---|
| ||||
Posted in reply to tony288 Attachments:
| On Thu, 2015-08-20 at 20:01 +0000, tony288 via Digitalmars-d-learn wrote: > […] > 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..? 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. -- Russel. ============================================================================= Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder@ekiga.net 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 |
Copyright © 1999-2021 by the D Language Foundation