View mode: basic / threaded / horizontal-split · Log in · Help
September 23, 2009
Re: Pure dynamic casts?
Jeremie Pelletier wrote:
> I myself couldn't live without threads or references, but I agree that
> mixing the two can lead to interesting scenarios to debug. Just try and
> code a responsive GUI without using threads, the application will "hang"
> everytime you're not going back to the main loop every few milliseconds.
> Or doing network I/O without bringing your program to a crawl, of course
> you could use async I/O but where is that I/O gonna run without a
> background thread to support it :)

<rant>

See, people equate "parallel execution" with "threads" these days which
is half the problem.  Threads are a TERRIBLE abstraction, because they
don't.  There's no protection.  Almost every time I express the opinion
that threads are broken, people automatically assume I think we should
all go back to single-core machines and cooperative multitasking.

It's like if I said I don't like Coke that I'm somehow against all
beverages.

A while ago, I was playing with a toy language design which used value
semantics for everything.  The one exception was references, but they
had two big differences from how, for example, D implements them:

1. They could only point to the heap, and could not point to any
pre-existing value.  If you, for example, took a ref to an array, it
would actually copy the array to the heap.

2. Refs to mutable values could only be dereferenced by their "owning"
thread; other threads couldn't even look at the contents.  A thread
could transfer ownership of a ref to another thread, or disown it
entirely at which point it became globally immutable.

Because of this, threads in the language couldn't even see each other's
mutable data (there were no process-globals, only thread-global); they
had to communicate via message passing.

In something like that, you don't need to worry about threads
interacting badly, because they can't interact except at specific points
in the program.

For something like a GUI, you'd have the GUI in one thread and do the
processing in another.  Instead of having to worry about locking and
synchronising, you just send the other thread a "do this" message.

Of course, something like that would never get into D.  Oh well.  :)

Where was I?

</rant>

> Besides, the upcoming shared qualifier is there to address those issues.
> 
> You might want to look at this article, I came across it a few months
> ago and found it rather insightful, it just could change your view on
> references:
> http://blogs.msdn.com/ericlippert/archive/2009/02/17/references-are-not-addresses.aspx

I've read it before.  It doesn't apply because we're talking about D,
not C#.  Conceptually, it's correct, but D is a systems programming
language.  If you're going to deal with things like the definition of
purity, then you HAVE to know what a reference really is and how it
works.  If you just use pure, you don't care.

It's like how if you're working on the CLR itself, you'd need to know
how references are implemented.  If you're USING the CLR, it's
immaterial in most cases.

In C#, if you talk about "Beethoven", then it's always the same
Beethoven.  The only way the definition of Beethoven would change is if
everyone in the universe forgot who he was first.

But in D, that's not entirely true.  You can hit the GC over the head
with a "delete" and it'll forget.  Sometimes it'll forget because you
accidentally stored the only remaining reference in a malloc'ed struct
RIGHT when some other thread triggered a collect and oh dear.

I would like to clarify, however, that I think it is fairly reasonable
to expect this optimisation to work.  It's just that I've been bitten by
threading issues so very many times that I work on the basis that given
half a chance, threading will completely screw your program.

That said, I think I'm getting too ranty, so I'll just leave it at that.
September 23, 2009
Re: Pure dynamic casts?
Daniel Keep wrote:
> Jeremie Pelletier wrote:
>> I myself couldn't live without threads or references, but I agree that
>> mixing the two can lead to interesting scenarios to debug. Just try and
>> code a responsive GUI without using threads, the application will "hang"
>> everytime you're not going back to the main loop every few milliseconds.
>> Or doing network I/O without bringing your program to a crawl, of course
>> you could use async I/O but where is that I/O gonna run without a
>> background thread to support it :)
> 
> <rant>
> 
> See, people equate "parallel execution" with "threads" these days which
> is half the problem.  Threads are a TERRIBLE abstraction, because they
> don't.  There's no protection.  Almost every time I express the opinion
> that threads are broken, people automatically assume I think we should
> all go back to single-core machines and cooperative multitasking.
> 
> It's like if I said I don't like Coke that I'm somehow against all
> beverages.
> 
> A while ago, I was playing with a toy language design which used value
> semantics for everything.  The one exception was references, but they
> had two big differences from how, for example, D implements them:
> 
> 1. They could only point to the heap, and could not point to any
> pre-existing value.  If you, for example, took a ref to an array, it
> would actually copy the array to the heap.
> 
> 2. Refs to mutable values could only be dereferenced by their "owning"
> thread; other threads couldn't even look at the contents.  A thread
> could transfer ownership of a ref to another thread, or disown it
> entirely at which point it became globally immutable.
> 
> Because of this, threads in the language couldn't even see each other's
> mutable data (there were no process-globals, only thread-global); they
> had to communicate via message passing.
> 
> In something like that, you don't need to worry about threads
> interacting badly, because they can't interact except at specific points
> in the program.
> 
> For something like a GUI, you'd have the GUI in one thread and do the
> processing in another.  Instead of having to worry about locking and
> synchronising, you just send the other thread a "do this" message.
> 
> Of course, something like that would never get into D.  Oh well.  :)
> 
> Where was I?
> 
> </rant>
> 
>> Besides, the upcoming shared qualifier is there to address those issues.
>>
>> You might want to look at this article, I came across it a few months
>> ago and found it rather insightful, it just could change your view on
>> references:
>> http://blogs.msdn.com/ericlippert/archive/2009/02/17/references-are-not-addresses.aspx
> 
> I've read it before.  It doesn't apply because we're talking about D,
> not C#.  Conceptually, it's correct, but D is a systems programming
> language.  If you're going to deal with things like the definition of
> purity, then you HAVE to know what a reference really is and how it
> works.  If you just use pure, you don't care.
> 
> It's like how if you're working on the CLR itself, you'd need to know
> how references are implemented.  If you're USING the CLR, it's
> immaterial in most cases.
> 
> In C#, if you talk about "Beethoven", then it's always the same
> Beethoven.  The only way the definition of Beethoven would change is if
> everyone in the universe forgot who he was first.
> 
> But in D, that's not entirely true.  You can hit the GC over the head
> with a "delete" and it'll forget.  Sometimes it'll forget because you
> accidentally stored the only remaining reference in a malloc'ed struct
> RIGHT when some other thread triggered a collect and oh dear.
> 
> I would like to clarify, however, that I think it is fairly reasonable
> to expect this optimisation to work.  It's just that I've been bitten by
> threading issues so very many times that I work on the basis that given
> half a chance, threading will completely screw your program.
> 
> That said, I think I'm getting too ranty, so I'll just leave it at that.

I dont believe there's such a thing as "too ranty", your post was quite 
insightful.

I understand your views on threading, ownership I believe is a feature 
planned for D3, but it wouldn't be that hard to implement on a custom 
runtime (i myself am still unsure about whether to do it or not yet). 
I've read Bartosz's entry about ownership, and I've looked at libraries 
using it (such as Qt). I think its a neat idea in itself, but I would 
rather see shared than ownership, or only using ownership on shared 
objects to keep things fast.

The thing is, you can share any piece of data, not just objects, 
therefore enforcing the ownership model would limit sharable data to 
objects, which is too limiting for many of us.

You're right about concurrency being a different concept than threading, 
 but I wouldn't give threading away for a pure concurrent model either. 
I believe D is aiming at giving programmers a choice of the tools they 
wish to use. I could see uses of both a concurrent model with message 
passing and a threading model with shared data used at once in a 
program. Shared data is always faster than message passing so you could 
implement real time code with it, and use messsage passing for other 
parts such as delegating GUI messages from the main loop.

Shared data being harder to manage than message passing does not make it 
a bad thing, it just means you can have two different models for two 
different usages.

I know the link I gave is for C# and this is D, but these are concepts 
not bound to any particular languages. I just wanted to point out that 
references in themselves aren't a bad idea, I find them much more 
convenient than pointers for objects and arrays, I just wish you had 
means to explicitly separate an object pointer from its data instead of 
only being able to use the reference which doesn't make the difference 
between the two syntactically.

Jeremie
September 24, 2009
Re: Pure dynamic casts?
Wed, 23 Sep 2009 15:09:59 +1000, Daniel Keep thusly wrote:

> See, people equate "parallel execution" with "threads" these days which
> is half the problem.  Threads are a TERRIBLE abstraction, because they
> don't.  There's no protection.  Almost every time I express the opinion
> that threads are broken, people automatically assume I think we should
> all go back to single-core machines and cooperative multitasking.

Threads come up every once in a while since they are one of the only ways 
to implement concurrency on the hardware level of shared memory machines. 
Another alternative is message passing. There just are no intelligent, 
dynamic low level models that provide e.g. abstractions and protection.

Once you realize this, the only way to build safe concurrent systems is 
to provide a safe high level abstraction on top of the hardware and 
transform programs written using this abstraction to use low level 
threads and messages. As the amount of concurrent threads keeps 
increasing, you start to value models that prevent things like deadlocks, 
starvation, and accidental concurrent writes to the same location.
September 25, 2009
Re: Pure dynamic casts?
Wed, 23 Sep 2009 10:43:53 -0400, Jeremie Pelletier thusly wrote:

> You're right about concurrency being a different concept than threading,
>   but I wouldn't give threading away for a pure concurrent model either.
> I believe D is aiming at giving programmers a choice of the tools they
> wish to use. I could see uses of both a concurrent model with message
> passing and a threading model with shared data used at once in a
> program.

The danger in too large a flexibility is that concurrency is not easy and 
it is getting incresingly complex. You need to be extraordinary good at 
manually managing all concurrent use of data. If I may predict something 
that is going to happen, it is that there will be high level models that 
avoid many low level pitfalls. These models will not provide 100% 
efficiency, but they are getting faster and faster, without compromizing 
the safety aspect. This already happened with memory allocation (manual 
vs garbage collection - in common applications, but not in special 
cases). Before that we gave some of the error detection capabilities to 
the compiler (e.g. we do not write array bounds checks ourselves 
anymore). And optimizations (e.g. register allocation). You may disagree, 
but I find it much more pleasant to find that the application does never 
crash even though it works 15% slower than an optimal C++ code would.

> Shared data is always faster than message passing so you could
> implement real time code with it, and use messsage passing for other
> parts such as delegating GUI messages from the main loop.

Shared data is maybe faster on shared memory machines, but this is not a 
fact in the general case.

> 
> Shared data being harder to manage than message passing does not make it
> a bad thing, it just means you can have two different models for two
> different usages.

Shared data is not a single homogenous model. Things like transactional 
memory work in shared memory systems, but still they have different 
semantics.
September 25, 2009
Re: Pure dynamic casts?
Fri, 25 Sep 2009 00:10:55 +0000, language_fan thusly wrote:

> You
> may disagree, but I find it much more pleasant to find that the
> application does never crash even though it works 15% slower than an
> optimal C++ code would.

Imagine if a buggy C++ program was monitoring your health. If it crashed 
or corrupted data, you would die. Yes, the C++ code would be $1M cheaper 
to build and the hardware would also be $100K cheaper (overall $10M vs 
$8.9M), but people would die 95% more often. Or in banking business the 
systems would handle 4x as much customers and transactions, but 
unfortunately some transactions would just go to the bit heaven due to 
the 5-6 reboots the mainframe required daily.
September 25, 2009
Re: Pure dynamic casts?
language_fan wrote:
> Wed, 23 Sep 2009 10:43:53 -0400, Jeremie Pelletier thusly wrote:
> 
>> You're right about concurrency being a different concept than threading,
>>   but I wouldn't give threading away for a pure concurrent model either.
>> I believe D is aiming at giving programmers a choice of the tools they
>> wish to use. I could see uses of both a concurrent model with message
>> passing and a threading model with shared data used at once in a
>> program.
> 
> The danger in too large a flexibility is that concurrency is not easy and 
> it is getting incresingly complex. You need to be extraordinary good at 
> manually managing all concurrent use of data. If I may predict something 
> that is going to happen, it is that there will be high level models that 
> avoid many low level pitfalls. These models will not provide 100% 
> efficiency, but they are getting faster and faster, without compromizing 
> the safety aspect. This already happened with memory allocation (manual 
> vs garbage collection - in common applications, but not in special 
> cases). Before that we gave some of the error detection capabilities to 
> the compiler (e.g. we do not write array bounds checks ourselves 
> anymore). And optimizations (e.g. register allocation). You may disagree, 
> but I find it much more pleasant to find that the application does never 
> crash even though it works 15% slower than an optimal C++ code would.

15% slower is an extreme performance hit. I agree that code safety is 
useful and I use this model all the time for initialization and other 
code which isn't real time, but 15% takes away a lot of the 
application's responsiveness, if you have 50 such applications running 
on your system you just spent $1000 more in hardware to get the 
performance of entry level hardware with faster code.

If you wrote a real time renderer for example with that 15% hit, you get 
a very noticeable difference in framerate. Not to mention standard GUIs 
to be laggy on slower machines (just MSN messenger runs to a crawl on my 
old computer, yet it can run the first UT which does way more operations 
per second, because there's no performance hit by safer code bloat).

>> Shared data is always faster than message passing so you could
>> implement real time code with it, and use messsage passing for other
>> parts such as delegating GUI messages from the main loop.
> 
> Shared data is maybe faster on shared memory machines, but this is not a 
> fact in the general case.
>
>> Shared data being harder to manage than message passing does not make it
>> a bad thing, it just means you can have two different models for two
>> different usages.
> 
> Shared data is not a single homogenous model. Things like transactional 
> memory work in shared memory systems, but still they have different 
> semantics.

Yes, I am well aware of that, I don't want to favor any particular 
design, I prefer to learn the semantics of a few of them and implement 
them all. Then I get the choice of the model to use depending on my needs.

Take search algorithm for example, you can pick between a binary search, 
b-tree r-tree, quadtree, octree, bsp, and a bunch of others along with 
dozens of variants of the ones mentionned depending on the data you're 
working with.

Its the same for concurrency, I can think of vector processing, 
functional calls, STM, message passing and shared memory off the top of 
my head. All being valid models with each their pros and cons, together 
forming a complete all-around solution.

Jeremie
September 25, 2009
Re: Pure dynamic casts?
language_fan wrote:
> Fri, 25 Sep 2009 00:10:55 +0000, language_fan thusly wrote:
> 
>> You
>> may disagree, but I find it much more pleasant to find that the
>> application does never crash even though it works 15% slower than an
>> optimal C++ code would.
> 
> Imagine if a buggy C++ program was monitoring your health. If it crashed 
> or corrupted data, you would die. Yes, the C++ code would be $1M cheaper 
> to build and the hardware would also be $100K cheaper (overall $10M vs 
> $8.9M), but people would die 95% more often. Or in banking business the 
> systems would handle 4x as much customers and transactions, but 
> unfortunately some transactions would just go to the bit heaven due to 
> the 5-6 reboots the mainframe required daily.

Then that just isn't production ready code, no matter the language. You 
could get the exact same behaviors with even the safest language ever.

A safe language does not prevent logic errors.

Jeremie
September 25, 2009
Re: Pure dynamic casts?
On Thu, 24 Sep 2009 20:46:13 -0400, Jeremie Pelletier <jeremiep@gmail.com>  
wrote:
[snip]
> Its the same for concurrency, I can think of vector processing,  
> functional calls, STM, message passing and shared memory off the top of  
> my head. All being valid models with each their pros and cons, together  
> forming a complete all-around solution.
>
> Jeremie
Don't forget task-based or lock-free.
September 25, 2009
Re: Pure dynamic casts?
Robert Jacques wrote:
> On Thu, 24 Sep 2009 20:46:13 -0400, Jeremie Pelletier 
> <jeremiep@gmail.com> wrote:
> [snip]
>> Its the same for concurrency, I can think of vector processing, 
>> functional calls, STM, message passing and shared memory off the top 
>> of my head. All being valid models with each their pros and cons, 
>> together forming a complete all-around solution.
>>
>> Jeremie
> Don't forget task-based or lock-free.

Oh yeah, thanks! Those were covered by Bartosz in his blog right? I 
think he used the term Actor for task based programming, I really 
enjoyed reading these articles.
September 25, 2009
Re: Pure dynamic casts?
Jeremie Pelletier wrote:
> language_fan wrote:
>> Wed, 23 Sep 2009 10:43:53 -0400, Jeremie Pelletier thusly wrote:
>>
>>> You're right about concurrency being a different concept than threading,
>>>   but I wouldn't give threading away for a pure concurrent model either.
>>> I believe D is aiming at giving programmers a choice of the tools they
>>> wish to use. I could see uses of both a concurrent model with message
>>> passing and a threading model with shared data used at once in a
>>> program.
>>
>> The danger in too large a flexibility is that concurrency is not easy 
>> and it is getting incresingly complex. You need to be extraordinary 
>> good at manually managing all concurrent use of data. If I may predict 
>> something that is going to happen, it is that there will be high level 
>> models that avoid many low level pitfalls. These models will not 
>> provide 100% efficiency, but they are getting faster and faster, 
>> without compromizing the safety aspect. This already happened with 
>> memory allocation (manual vs garbage collection - in common 
>> applications, but not in special cases). Before that we gave some of 
>> the error detection capabilities to the compiler (e.g. we do not write 
>> array bounds checks ourselves anymore). And optimizations (e.g. 
>> register allocation). You may disagree, but I find it much more 
>> pleasant to find that the application does never crash even though it 
>> works 15% slower than an optimal C++ code would.
> 
> 15% slower is an extreme performance hit. I agree that code safety is 
> useful and I use this model all the time for initialization and other 
> code which isn't real time, but 15% takes away a lot of the 
> application's responsiveness, if you have 50 such applications running 
> on your system you just spent $1000 more in hardware to get the 
> performance of entry level hardware with faster code.

What are most applications these days? MS Office, a web browser, maybe 
an email client, some odds and ends, and a whole bunch of web sites 
running on servers somewhere (with associated database servers and some 
other odds and ends).

How much does it cost to get a slightly better machine? Fully hosted? 
Maybe $100/month.

How much does it cost to develop it in a faster but more error-prone 
language? Maybe months more time to market, time you're not making money 
but are still paying developers. Those developers will need to be more 
skilled than the ones using a safer language, and thus will cost you 
more. New features will take more time to develop.

It's a competitive advantage to use a slower, safer language on the web.

Desktop applications are not quite so straightforward.

> If you wrote a real time renderer for example with that 15% hit, you get 
> a very noticeable difference in framerate. Not to mention standard GUIs 
> to be laggy on slower machines (just MSN messenger runs to a crawl on my 
> old computer, yet it can run the first UT which does way more operations 
> per second, because there's no performance hit by safer code bloat).

Games are not interesting in this regard. They require performance, and 
they're hideously expensive. A studio can throw developers at the 
problems and make them go away.

Not all games are like this, of course. But most are.
1 2 3 4 5 6
Top | Discussion index | About this forum | D home