Re: Cleaned up C++

2015-04-27 Thread ketmar via Digitalmars-d
On Mon, 27 Apr 2015 08:23:26 +, ponce wrote:

 Bringing D in the workplace often bring incredible resistance and
 arguments.
 
 I've heard it all over the years:
 - D is like C#, why use it?
 - D can't be scripted (yes it can)
 - D isn't fast enough
 - D isn't much used and is 10 years old, there must be problems
 - D isn't used enough
 
 Much like C++ was met with resistance?
 Meanwhile D programs get written and consistently over-deliver on
 promises.

D has one thing that kills C++ instantly, though: modules (and 
declaration order). anyone who had a joy to work on big project with C or 
C++ will sell his soul for module system.

signature.asc
Description: PGP signature


Re: Cleaned up C++

2015-04-27 Thread Laeeth Isharc via Digitalmars-d

On Sunday, 26 April 2015 at 19:13:33 UTC, ponce wrote:

On Sunday, 26 April 2015 at 14:28:11 UTC, Baz wrote:

On Sunday, 26 April 2015 at 12:04:20 UTC, Laeeth Isharc wrote:

On Sunday, 26 April 2015 at 09:26:11 UTC, ponce wrote:

On Wednesday, 22 April 2015 at 19:51:23 UTC, ponce wrote:


I should put in in a d-idioms anyway.



http://p0nce.github.io/d-idioms/#How-does-D-improve-on-C++17?


excellent.

I linked it here: http://wiki.dlang.org/Coming_From


Luke 4:24 nobody is prophet in his own country

http://www.reddit.com/r/programming/comments/33x6lj/how_does_d_improve_on_c17/


Lesson taken: should have put a less aggressive title.


Not necessarily.  The people who complain loudly constitute a 
tiny subset of those who are ultimately influenced.  One can't 
walk through life in fear of criticism, and if you believe D is 
superior in this respect and backed it up (which it seemed to me 
you did), then I think it's more effective to say so and prepare 
for the inevitable brickbats than to placate those who will 
always find a reason to attack you ;)


In any case, some really good stuff in your idioms.  Maybe worth 
turning into a longer blog piece that recounts in a personal 
voice your experience of using D as a C++ guy.


Re: Cleaned up C++

2015-04-27 Thread ponce via Digitalmars-d

On Monday, 27 April 2015 at 07:45:30 UTC, Laeeth Isharc wrote:

On Sunday, 26 April 2015 at 19:13:33 UTC, ponce wrote:


Lesson taken: should have put a less aggressive title.


Not necessarily.  The people who complain loudly constitute a 
tiny subset of those who are ultimately influenced.  One can't 
walk through life in fear of criticism, and if you believe D is 
superior in this respect and backed it up (which it seemed to 
me you did), then I think it's more effective to say so and 
prepare for the inevitable brickbats than to placate those who 
will always find a reason to attack you ;)




Good advice, thanks! It seems the more assertive tones often get 
less criticism.


In any case, some really good stuff in your idioms.  Maybe 
worth turning into a longer blog piece that recounts in a 
personal voice your experience of using D as a C++ guy.


Thanks. There might be errors in places.

Bringing D in the workplace often bring incredible resistance and 
arguments.


I've heard it all over the years:
- D is like C#, why use it?
- D can't be scripted (yes it can)
- D isn't fast enough
- D isn't much used and is 10 years old, there must be problems
- D isn't used enough

Much like C++ was met with resistance?
Meanwhile D programs get written and consistently over-deliver on 
promises.


Re: Cleaned up C++

2015-04-26 Thread ponce via Digitalmars-d

On Wednesday, 22 April 2015 at 19:51:23 UTC, ponce wrote:


I should put in in a d-idioms anyway.



http://p0nce.github.io/d-idioms/#How-does-D-improve-on-C++17?


Re: Cleaned up C++

2015-04-26 Thread Baz via Digitalmars-d

On Sunday, 26 April 2015 at 12:04:20 UTC, Laeeth Isharc wrote:

On Sunday, 26 April 2015 at 09:26:11 UTC, ponce wrote:

On Wednesday, 22 April 2015 at 19:51:23 UTC, ponce wrote:


I should put in in a d-idioms anyway.



http://p0nce.github.io/d-idioms/#How-does-D-improve-on-C++17?


excellent.

I linked it here: http://wiki.dlang.org/Coming_From


Luke 4:24 nobody is prophet in his own country

http://www.reddit.com/r/programming/comments/33x6lj/how_does_d_improve_on_c17/



Re: Cleaned up C++

2015-04-26 Thread Laeeth Isharc via Digitalmars-d

On Sunday, 26 April 2015 at 09:26:11 UTC, ponce wrote:

On Wednesday, 22 April 2015 at 19:51:23 UTC, ponce wrote:


I should put in in a d-idioms anyway.



http://p0nce.github.io/d-idioms/#How-does-D-improve-on-C++17?


excellent.

I linked it here: http://wiki.dlang.org/Coming_From



Re: Cleaned up C++

2015-04-26 Thread ponce via Digitalmars-d

On Sunday, 26 April 2015 at 14:28:11 UTC, Baz wrote:

On Sunday, 26 April 2015 at 12:04:20 UTC, Laeeth Isharc wrote:

On Sunday, 26 April 2015 at 09:26:11 UTC, ponce wrote:

On Wednesday, 22 April 2015 at 19:51:23 UTC, ponce wrote:


I should put in in a d-idioms anyway.



http://p0nce.github.io/d-idioms/#How-does-D-improve-on-C++17?


excellent.

I linked it here: http://wiki.dlang.org/Coming_From


Luke 4:24 nobody is prophet in his own country

http://www.reddit.com/r/programming/comments/33x6lj/how_does_d_improve_on_c17/


Lesson taken: should have put a less aggressive title.


Re: Cleaned up C++

2015-04-25 Thread Walter Bright via Digitalmars-d

On 4/24/2015 11:51 PM, Iain Buclaw via Digitalmars-d wrote:

I wonder just how large...  IIRC I think the limit on ubyte arrays is 1M?


A large enough value can not just case stack overflow, but can cause the stack 
pointer to be anywhere in the address space.


I don't know of a limit on ubyte arrays.


Re: Cleaned up C++

2015-04-25 Thread Andrei Alexandrescu via Digitalmars-d

On 4/22/15 1:36 PM, John Colvin wrote:


Is it even possible to contrive a case where
1) The default initialisation stores are technically dead and
2) Modern compilers can't tell they are dead and elide them and
3) Doing the initialisation has a significant performance impact?

The boring example is extra code causes instruction cache misses.


I've seen statically-sized arrays causing problems. -- Andrei


Re: Cleaned up C++

2015-04-25 Thread John Colvin via Digitalmars-d
On Saturday, 25 April 2015 at 21:26:25 UTC, Andrei Alexandrescu 
wrote:

On 4/22/15 1:36 PM, John Colvin wrote:


Is it even possible to contrive a case where
1) The default initialisation stores are technically dead and
2) Modern compilers can't tell they are dead and elide them and
3) Doing the initialisation has a significant performance 
impact?


The boring example is extra code causes instruction cache 
misses.


I've seen statically-sized arrays causing problems. -- Andrei


Care to outline an example?


Re: Cleaned up C++

2015-04-25 Thread Andrei Alexandrescu via Digitalmars-d

On 4/25/15 3:23 PM, John Colvin wrote:

On Saturday, 25 April 2015 at 21:26:25 UTC, Andrei Alexandrescu wrote:

On 4/22/15 1:36 PM, John Colvin wrote:


Is it even possible to contrive a case where
1) The default initialisation stores are technically dead and
2) Modern compilers can't tell they are dead and elide them and
3) Doing the initialisation has a significant performance impact?

The boring example is extra code causes instruction cache misses.


I've seen statically-sized arrays causing problems. -- Andrei


Care to outline an example?


Many examples have to do with sentinel-terminated buffers. Start with e.g.

char buf[1024] = void;
buf[0] = 0;
...

The rest of the function makes sure it keeps the invariant that the 
buffer is zero-terminated. This is difficult for compilers to divine 
(never saw any to do so). So you have either code that's officially 
unsafe because it uses uninitialized data, or slow code because it 
zeroes the entire kilobyte.


No more need to get into details here, because... IT'S HACKATHON TIME! 
I'll post my ideas next.



Andrei



Re: Cleaned up C++

2015-04-25 Thread Iain Buclaw via Digitalmars-d
On 25 Apr 2015 01:25, Walter Bright via Digitalmars-d 
digitalmars-d@puremagic.com wrote:

 On 4/24/2015 5:59 AM, John Colvin wrote:

 one reason why it might be faster is that e.g. gcc can produce code like
this:

 #includealloca.h

 void bar(char* a);

 void foo(unsigned int n)
 {
char *a = (char*)alloca(n);
bar(a);
 }

 foo:
  movl%edi, %eax
  pushq%rbp
  addq$46, %rax
  movq%rsp, %rbp
  shrq$4, %rax
  salq$4, %rax
  subq%rax, %rsp
  leaq31(%rsp), %rdi
  andq$-32, %rdi
  callbar
  leave
  ret

 which is neat.


 It's a cowboy implementation that's fine until it someone tries a largish
value of n.


I wonder just how large...  IIRC I think the limit on ubyte arrays is 1M?


Re: Cleaned up C++

2015-04-24 Thread Daniel Murphy via Digitalmars-d

Walter Bright  wrote in message news:mhc7am$942$1...@digitalmars.com...


Everyone hated it :-) but me.


And by that Walter means the interface was highly unsafe and he didn't want 
to change it. 



Re: Cleaned up C++

2015-04-24 Thread Walter Bright via Digitalmars-d

On 4/24/2015 12:23 AM, John Colvin wrote:

Except of course that alloca is a lot cheaper than malloc/free.


That's not necessarily true. But in any case, go ahead and use it if you like. 
Just prepare to benchmark and be disappointed :-)


Re: Cleaned up C++

2015-04-24 Thread ponce via Digitalmars-d

On Friday, 24 April 2015 at 08:16:40 UTC, Walter Bright wrote:

On 4/24/2015 12:23 AM, John Colvin wrote:

Except of course that alloca is a lot cheaper than malloc/free.


That's not necessarily true. But in any case, go ahead and use 
it if you like. Just prepare to benchmark and be disappointed 
:-)


Do you have a guess for why and when it could not be faster than 
malloc in times?
I have some difficulty imagining a reason (yet I have sometimes 
found malloc faster than aligned_malloc which is another odd 
thing).


Re: Cleaned up C++

2015-04-24 Thread John Colvin via Digitalmars-d

On Friday, 24 April 2015 at 12:34:19 UTC, ponce wrote:

On Friday, 24 April 2015 at 08:16:40 UTC, Walter Bright wrote:

On 4/24/2015 12:23 AM, John Colvin wrote:
Except of course that alloca is a lot cheaper than 
malloc/free.


That's not necessarily true. But in any case, go ahead and use 
it if you like. Just prepare to benchmark and be disappointed 
:-)


Do you have a guess for why and when it could not be faster 
than malloc in times?
I have some difficulty imagining a reason (yet I have sometimes 
found malloc faster than aligned_malloc which is another odd 
thing).


one reason why it might be faster is that e.g. gcc can produce 
code like this:


#includealloca.h

void bar(char* a);

void foo(unsigned int n)
{
  char *a = (char*)alloca(n);
  bar(a);
}

foo:
movl%edi, %eax
pushq   %rbp
addq$46, %rax
movq%rsp, %rbp
shrq$4, %rax
salq$4, %rax
subq%rax, %rsp
leaq31(%rsp), %rdi
andq$-32, %rdi
callbar
leave
ret

which is neat. Now of course a push-the-pointer malloc/free 
implementation could perhaps be (in theory) optimised to be as 
small as this, but is that ever actually the case?


Re: Cleaned up C++

2015-04-24 Thread deadalnix via Digitalmars-d

On Friday, 24 April 2015 at 08:16:40 UTC, Walter Bright wrote:

On 4/24/2015 12:23 AM, John Colvin wrote:

Except of course that alloca is a lot cheaper than malloc/free.


That's not necessarily true. But in any case, go ahead and use 
it if you like. Just prepare to benchmark and be disappointed 
:-)


It is, unless one go the bump the pointer/never free road.


Re: Cleaned up C++

2015-04-24 Thread Walter Bright via Digitalmars-d

On 4/24/2015 10:27 AM, deadalnix wrote:

On Friday, 24 April 2015 at 08:16:40 UTC, Walter Bright wrote:

On 4/24/2015 12:23 AM, John Colvin wrote:

Except of course that alloca is a lot cheaper than malloc/free.


That's not necessarily true. But in any case, go ahead and use it if you like.
Just prepare to benchmark and be disappointed :-)


It is, unless one go the bump the pointer/never free road.


I wouldn't assume that. A large array on the stack will have memory caching 
issues.


Re: Cleaned up C++

2015-04-24 Thread Walter Bright via Digitalmars-d

On 4/24/2015 5:59 AM, John Colvin wrote:

one reason why it might be faster is that e.g. gcc can produce code like this:

#includealloca.h

void bar(char* a);

void foo(unsigned int n)
{
   char *a = (char*)alloca(n);
   bar(a);
}

foo:
 movl%edi, %eax
 pushq%rbp
 addq$46, %rax
 movq%rsp, %rbp
 shrq$4, %rax
 salq$4, %rax
 subq%rax, %rsp
 leaq31(%rsp), %rdi
 andq$-32, %rdi
 callbar
 leave
 ret

which is neat.


It's a cowboy implementation that's fine until it someone tries a largish value 
of n.




Re: Cleaned up C++

2015-04-24 Thread John Colvin via Digitalmars-d

On Friday, 24 April 2015 at 01:54:11 UTC, Walter Bright wrote:

On 4/23/2015 3:11 PM, deadalnix wrote:

For arbitrary large, you can always do something like :

Item* itemPtr = (arbitrarylarge  thresold)
  ? alloca(arbitrarylarge)
  : GC.alloc(arbitrarylarge);

One extra check compared to a heap allocation is not going to 
make things
terrible, and it is likely to be very predictible anyway (most 
arbitrarylarge

size are actually small in practice).


You can, but it just doesn't pay off. Even if you found a case 
that did, it doesn't mean it pays off in general, and so would 
be poor advice.


BTW, since alloca() doesn't survive function scope, might as 
well use malloc/free instead of the GC. Or do like I've done 
and have an array of preallocated larger buffers.


I.e. if you've gotten to tuning code at this level, the 
compiler picking things automatically for you is unlikely to be 
helpful. Hence my not being convinced by bearophile's 
assessment.


Except of course that alloca is a lot cheaper than malloc/free.


Re: Cleaned up C++

2015-04-23 Thread via Digitalmars-d

On Wednesday, 22 April 2015 at 22:26:45 UTC, John Colvin wrote:
On Wednesday, 22 April 2015 at 21:59:48 UTC, Ola Fosheim 
Grøstad wrote:

On Wednesday, 22 April 2015 at 20:36:12 UTC, John Colvin wrote:

Is it even possible to contrive a case where
1) The default initialisation stores are technically dead and
2) Modern compilers can't tell they are dead and elide them 
and
3) Doing the initialisation has a significant performance 
impact?


The boring example is extra code causes instruction cache 
misses.


Allocation of large arrays.


That doesn't really answer the question without some more 
context.


I think it does.

Compilers cannot tell what goes on because they cannot figure out 
nontrivial loop invariants without guidance. You need something 
like a theorem prover (coq?)...


Compilers may not be about to tell arrays won't be touched 
because of memory barriers when calling external functions, so 
they have to complete initialization before that. Presumably a 
Rust compiler could do better...



Can you give a specific example where all 3 points are
satisfied?


Not sure why you would need it, plenty of cases where compilers 
will fail. E.g. queues between threads (like real time threads) 
where you allocate in one thread and fill out data in another 
thread.


Any preallocation done on large data structures or frequently 
reinitialized data structures may perform better without explicit 
initialization.


For a system level language I think it would be better to verify 
that you don't use noninitialized memory using a theorem prover 
(sanitizer) or to use guards (like NaN). Automatic initialization 
is also a source of bugs.




Re: Cleaned up C++

2015-04-23 Thread Iain Buclaw via Digitalmars-d
On 23 April 2015 at 16:28, via Digitalmars-d
digitalmars-d@puremagic.com wrote:
 On Wednesday, 22 April 2015 at 22:26:45 UTC, John Colvin wrote:

 On Wednesday, 22 April 2015 at 21:59:48 UTC, Ola Fosheim Grøstad wrote:

 On Wednesday, 22 April 2015 at 20:36:12 UTC, John Colvin wrote:

 Is it even possible to contrive a case where
 1) The default initialisation stores are technically dead and
 2) Modern compilers can't tell they are dead and elide them and
 3) Doing the initialisation has a significant performance impact?

 The boring example is extra code causes instruction cache misses.


 Allocation of large arrays.


 That doesn't really answer the question without some more context.


 I think it does.

 Compilers cannot tell what goes on because they cannot figure out nontrivial
 loop invariants without guidance. You need something like a theorem prover
 (coq?)...


There are two states each local variable can be assigned.
1. Used
2. Read

int a = 1;  // a = Used
return a;  // a = Read
printf(%d\n, a);  // a = Read
int b = a;  // b = Used, a = Read
int c = void; // c = Unused

If a variable is unused, it's a dead variable.  If a variable is used
but not read, it's a dead variable. Simple. :-)



Re: Cleaned up C++

2015-04-23 Thread John Colvin via Digitalmars-d
On Thursday, 23 April 2015 at 14:29:01 UTC, Ola Fosheim Grøstad 
wrote:

Can you give a specific example where all 3 points are
satisfied?


Not sure why you would need it, plenty of cases where compilers 
will fail. E.g. queues between threads (like real time threads) 
where you allocate in one thread and fill out data in another 
thread.


Any preallocation done on large data structures or frequently 
reinitialized data structures may perform better without 
explicit initialization.


Yes, there are times the compiler can't optimise the dead stores 
away. Obviously these dead stores are not free. What I don't see 
is a good example of when that cost matters.


There are cases where you might really need to grab an extra 
1-5%, at which point you are hand optimising and = void is a 
reasonable tool.


Re: Cleaned up C++

2015-04-23 Thread via Digitalmars-d

On Thursday, 23 April 2015 at 14:50:26 UTC, John Colvin wrote:
There are cases where you might really need to grab an extra 
1-5%, at which point you are hand optimising and = void is a 
reasonable tool.


Well, it can be a lot more than 1-5% in special situations if you 
hand over a small header request with a bundled array to fill in, 
so =void can be important.


But the real down side by making automatic initialization part of 
the language semantics is that you cannot do machine verfication 
where you detect cases where you forgot actual initialization. 
E.g. indexing where you should start at 1 and not 0.


That's not so good for correctness.

It's the same issue with modular arithmetics which actually 
remove overflows from integer operations, but then you cannot use 
machine verification to detect overflow either (unless you are 
happy with a large number of false positives).




Re: Cleaned up C++

2015-04-23 Thread via Digitalmars-d

On Thursday, 23 April 2015 at 14:55:42 UTC, Iain Buclaw wrote:

There are two states each local variable can be assigned.
1. Used
2. Read

int a = 1;  // a = Used
return a;  // a = Read
printf(%d\n, a);  // a = Read
int b = a;  // b = Used, a = Read
int c = void; // c = Unused

If a variable is unused, it's a dead variable.  If a variable 
is used

but not read, it's a dead variable. Simple. :-)


Proving how indexing of an array hits the array in a nontrivial 
loop is intractable for large N (any parameter you like).


(you also don't deal with binary true/false, but three outcomes: 
satisfiable, unsatisfiable and unknown)


Re: Cleaned up C++

2015-04-23 Thread Walter Bright via Digitalmars-d

On 4/23/2015 1:10 AM, bearophile wrote:

Walter Bright:


On 4/22/2015 2:58 PM, bearophile wrote:

D is less stack-friendly than Ada (and probably Rust too),


??


In Ada standard library you have safe fixed-size stack-allocated associative
arrays. In D you can't even allocate safely a dynamically-sized 1D array on the
stack, and forget about doing it for 2D. Enough said.


I used to use alloca() here and there, but eventually removed it all. The 
trouble is, there are three array sizes:


   a) 0
   b) 1
   c) arbitrarily large

Dynamic stack allocation works for none of them. What does work is a fixed size 
stack allocation with failover to using malloc/free, which is what Phobos' 
scopebuffer does. It's analogous to the small string optimization.


I don't agree with your assessment at all.



Re: Cleaned up C++

2015-04-23 Thread John Colvin via Digitalmars-d

On Thursday, 23 April 2015 at 18:37:47 UTC, Walter Bright wrote:

On 4/23/2015 1:10 AM, bearophile wrote:

Walter Bright:


On 4/22/2015 2:58 PM, bearophile wrote:

D is less stack-friendly than Ada (and probably Rust too),


??


In Ada standard library you have safe fixed-size 
stack-allocated associative
arrays. In D you can't even allocate safely a 
dynamically-sized 1D array on the

stack, and forget about doing it for 2D. Enough said.


I used to use alloca() here and there, but eventually removed 
it all. The trouble is, there are three array sizes:


   a) 0
   b) 1
   c) arbitrarily large

Dynamic stack allocation works for none of them. What does work 
is a fixed size stack allocation with failover to using 
malloc/free, which is what Phobos' scopebuffer does. It's 
analogous to the small string optimization.


I don't agree with your assessment at all.


I used to think this was totally wrong, but over time I've come 
to see your point.


The ideal for me would be a dynamically sized stack array (C99 
style, not alloca) with a compile-time maximum size. Then you 
wrap that in a library type that decides/defines what to do when 
the size is exceeded (e.g. move to GC heap a la scopeBuffer), but 
in practice it's not a big win over just stack allocating the 
maximum size all the time (again, like scopeBuffer).


Re: Cleaned up C++

2015-04-23 Thread weaselcat via Digitalmars-d

On Thursday, 23 April 2015 at 18:37:47 UTC, Walter Bright wrote:

On 4/23/2015 1:10 AM, bearophile wrote:

Walter Bright:


On 4/22/2015 2:58 PM, bearophile wrote:

D is less stack-friendly than Ada (and probably Rust too),


??


In Ada standard library you have safe fixed-size 
stack-allocated associative
arrays. In D you can't even allocate safely a 
dynamically-sized 1D array on the

stack, and forget about doing it for 2D. Enough said.


I used to use alloca() here and there, but eventually removed 
it all. The trouble is, there are three array sizes:


   a) 0
   b) 1
   c) arbitrarily large

Dynamic stack allocation works for none of them. What does work 
is a fixed size stack allocation with failover to using 
malloc/free, which is what Phobos' scopebuffer does. It's 
analogous to the small string optimization.


I don't agree with your assessment at all.


Is there a reason scopebuffer isn't part of the documentation?


Re: Cleaned up C++

2015-04-23 Thread via Digitalmars-d

On Thursday, 23 April 2015 at 20:40:36 UTC, John Colvin wrote:
scopeBuffer), but in practice it's not a big win over just 
stack allocating the maximum size all the time (again, like 
scopeBuffer).


If you have a random distribution of sizes then allocating the 
maximum will use twice as much memory. That affects cache 
performance.


Re: Cleaned up C++

2015-04-23 Thread deadalnix via Digitalmars-d

On Thursday, 23 April 2015 at 18:37:47 UTC, Walter Bright wrote:

On 4/23/2015 1:10 AM, bearophile wrote:

Walter Bright:


On 4/22/2015 2:58 PM, bearophile wrote:

D is less stack-friendly than Ada (and probably Rust too),


??


In Ada standard library you have safe fixed-size 
stack-allocated associative
arrays. In D you can't even allocate safely a 
dynamically-sized 1D array on the

stack, and forget about doing it for 2D. Enough said.


I used to use alloca() here and there, but eventually removed 
it all. The trouble is, there are three array sizes:


   a) 0
   b) 1
   c) arbitrarily large

Dynamic stack allocation works for none of them. What does work 
is a fixed size stack allocation with failover to using 
malloc/free, which is what Phobos' scopebuffer does. It's 
analogous to the small string optimization.


I don't agree with your assessment at all.


For arbitrary large, you can always do something like :

Item* itemPtr = (arbitrarylarge  thresold)
  ? alloca(arbitrarylarge)
  : GC.alloc(arbitrarylarge);

One extra check compared to a heap allocation is not going to 
make things terrible, and it is likely to be very predictible 
anyway (most arbitrarylarge size are actually small in practice).


The compiler could even do it at optimizer level.


Re: Cleaned up C++

2015-04-23 Thread John Colvin via Digitalmars-d

On Thursday, 23 April 2015 at 01:45:14 UTC, deadalnix wrote:

On Wednesday, 22 April 2015 at 20:36:12 UTC, John Colvin wrote:

Is it even possible to contrive a case where
1) The default initialisation stores are technically dead and
2) Modern compilers can't tell they are dead and elide them and
3) Doing the initialisation has a significant performance 
impact?


The boring example is extra code causes instruction cache 
misses.


I'd say it is very unlikely. If the compiler wan't see it, then 
it means the code is non trivial, and if it is non trivial, it 
is not an extra store that is going to make any difference.


This was my thinking. I guess you could have something like this:

extern(C) void myCheapInitialiser(float*, size_t);
float[256] a;
myCheapInitialiser(a.ptr, a.length);
sort(a);
writeln(a.stride(2).sum());


Re: Cleaned up C++

2015-04-23 Thread Iain Buclaw via Digitalmars-d
 On Wednesday, 22 April 2015 at 20:29:49 UTC, Walter Bright wrote:

 On 4/22/2015 12:51 PM, ponce wrote:

 I didn't appreciate how important default initialization was before
 having to
 fix a non-deterministic, release-only, time-dependent bug in a video
 encoder
 some months ago. Just because of 2 uninitialized variables (C++ doesn't
 require
 member initialization in constructor). If one of them was _exactly equal
 to 1_
 by virtue of randomness, then it would perform from 0 to 2 billions of
 motion
 estimation steps, which is very slow but not a total halt. A watchdog
 mechanism
 would detect this and reboot, hence labelling the bug a deadlock. It
 would
 disappear in debug mode since variables would be initialized then.


 The default initialization comes from bitter personal experience, much
 like yours!


 That gives a totally other meaning to zero cost abstractions since in
 three
 weeks of investigation I could have speed-up the program by ~5%, much
 more than
 the supposed slowdown of variable initialization.


 Most of the implicit initializations become dead stores and are removed
 anyway by the optimizer.

Right, on simple types (scalars, pointers) which have a trivial
initialisation, the compiler is able to track their value until it is
read and use DCE to remove previous initialisations up to that point.

(Contrived) Examples:

void dce1()
{
int dead_int;
printf(Dead Int\n);
}

void dce2()
{
int inited_later;
int dead_int;
inited_later = 42;
printf(Initialized Int = %d\n, inited_later);
}

---

gdc -O -fdump-tree-optimized=stderr dce.d

dce1 ()
{
  __builtin_puts (Dead Int[0]);
  return;
}

dce2 ()
{
  __builtin_printf (Initialized Int = %d\n, 42);
  return;
}

---

As pointed out, there are limitations when it comes to types which
have a complex initialiser.

On 22 April 2015 at 22:36, John Colvin via Digitalmars-d
digitalmars-d@puremagic.com wrote:

 Is it even possible to contrive a case where
 1) The default initialisation stores are technically dead and

int arrayInit()
{
return 0xdeadbeef;
}

void main()
{
int[ushort.max] dead_array = arrayInit();
printf(Dead Array\n);
}

 2) Modern compilers can't tell they are dead and elide them and

Actually - gdc can DCE the array initialisation at -O3, but I'd like
to do better than that in future...

gdc -O3 -fdump-tree-optimized=stderr dce.d
D main ()
{
  unsigned int ivtmp.20;
  int dead_array[65535];
  unsigned int _1;
  void * _13;

  bb 2:
  # DEBUG D.3569 = dead_array
  # DEBUG D.3570 = 65535
  ivtmp.20_12 = (unsigned int) dead_array;
  _1 = (unsigned int) MEM[(void *)dead_array + 262128B];

  bb 3:
  # ivtmp.20_16 = PHI ivtmp.20_3(3), ivtmp.20_12(2)
  _13 = (void *) ivtmp.20_16;
  MEM[base: _13, offset: 0B] = { -559038737, -559038737, -559038737,
-559038737 };
  ivtmp.20_3 = ivtmp.20_16 + 16;
  if (_1 == ivtmp.20_3)
goto bb 4;
  else
goto bb 3;

  bb 4:
  __builtin_puts (Dead Array[0]);
  dead_array ={v} {CLOBBER};
  return 0;

}

 3) Doing the initialisation has a significant performance impact?

Short answer, no.

time ./a.out
Dead Array

real0m0.001s
user0m0.000s
sys0m0.001s


Worded answer, static array overflow analysis means that you can't get
an array much higher than 1M, and the compiler can quite happily
vectorised the initialisation process for you so there's fewer loops
to go round.  However if there was a 'lazy + impure' initialiser, that
would be a different story.  :-)

Iain.


Re: Cleaned up C++

2015-04-23 Thread bearophile via Digitalmars-d

Walter Bright:


On 4/22/2015 2:58 PM, bearophile wrote:

D is less stack-friendly than Ada (and probably Rust too),


??


In Ada standard library you have safe fixed-size stack-allocated 
associative arrays. In D you can't even allocate safely a 
dynamically-sized 1D array on the stack, and forget about doing 
it for 2D. Enough said.


Bye,
bearophile


Re: Cleaned up C++

2015-04-23 Thread Walter Bright via Digitalmars-d

On 4/23/2015 2:54 PM, weaselcat wrote:

Is there a reason scopebuffer isn't part of the documentation?


Everyone hated it :-) but me.


Re: Cleaned up C++

2015-04-23 Thread Walter Bright via Digitalmars-d

On 4/23/2015 3:11 PM, deadalnix wrote:

For arbitrary large, you can always do something like :

Item* itemPtr = (arbitrarylarge  thresold)
   ? alloca(arbitrarylarge)
   : GC.alloc(arbitrarylarge);

One extra check compared to a heap allocation is not going to make things
terrible, and it is likely to be very predictible anyway (most arbitrarylarge
size are actually small in practice).


You can, but it just doesn't pay off. Even if you found a case that did, it 
doesn't mean it pays off in general, and so would be poor advice.


BTW, since alloca() doesn't survive function scope, might as well use 
malloc/free instead of the GC. Or do like I've done and have an array of 
preallocated larger buffers.


I.e. if you've gotten to tuning code at this level, the compiler picking things 
automatically for you is unlikely to be helpful. Hence my not being convinced by 
bearophile's assessment.


Cleaned up C++

2015-04-22 Thread Walter Bright via Digitalmars-d

I'd missed this post on reddit:

http://www.reddit.com/r/programming/comments/30wj8g/managing_cs_complexity_or_learning_to_enjoy_c/cpx41ix


Re: Cleaned up C++

2015-04-22 Thread weaselcat via Digitalmars-d

On Wednesday, 22 April 2015 at 19:29:08 UTC, Walter Bright wrote:
D is just another of those “Let's put everything on the 
heap”-languages that do then of course need GC.


what's up with people constantly equating garbage collection to 
being the same as java?


Re: Cleaned up C++

2015-04-22 Thread ponce via Digitalmars-d

On Wednesday, 22 April 2015 at 19:29:08 UTC, Walter Bright wrote:

I'd missed this post on reddit:

http://www.reddit.com/r/programming/comments/30wj8g/managing_cs_complexity_or_learning_to_enjoy_c/cpx41ix


Thanks for the mention. I must have forgotten some. I should put 
in in a d-idioms anyway.


I didn't appreciate how important default initialization was 
before having to fix a non-deterministic, release-only, 
time-dependent bug in a video encoder some months ago. Just 
because of 2 uninitialized variables (C++ doesn't require member 
initialization in constructor). If one of them was _exactly equal 
to 1_ by virtue of randomness, then it would perform from 0 to 2 
billions of motion estimation steps, which is very slow but not a 
total halt. A watchdog mechanism would detect this and reboot, 
hence labelling the bug a deadlock. It would disappear in debug 
mode since variables would be initialized then.


That gives a totally other meaning to zero cost abstractions 
since in three weeks of investigation I could have speed-up the 
program by ~5%, much more than the supposed slowdown of variable 
initialization.





Re: Cleaned up C++

2015-04-22 Thread deadalnix via Digitalmars-d

On Wednesday, 22 April 2015 at 20:36:12 UTC, John Colvin wrote:

Is it even possible to contrive a case where
1) The default initialisation stores are technically dead and
2) Modern compilers can't tell they are dead and elide them and
3) Doing the initialisation has a significant performance 
impact?


The boring example is extra code causes instruction cache 
misses.


I'd say it is very unlikely. If the compiler wan't see it, then 
it means the code is non trivial, and if it is non trivial, it is 
not an extra store that is going to make any difference.


Re: Cleaned up C++

2015-04-22 Thread John Colvin via Digitalmars-d

On Wednesday, 22 April 2015 at 20:29:49 UTC, Walter Bright wrote:

On 4/22/2015 12:51 PM, ponce wrote:
I didn't appreciate how important default initialization was 
before having to
fix a non-deterministic, release-only, time-dependent bug in a 
video encoder
some months ago. Just because of 2 uninitialized variables 
(C++ doesn't require
member initialization in constructor). If one of them was 
_exactly equal to 1_
by virtue of randomness, then it would perform from 0 to 2 
billions of motion
estimation steps, which is very slow but not a total halt. A 
watchdog mechanism
would detect this and reboot, hence labelling the bug a 
deadlock. It would
disappear in debug mode since variables would be initialized 
then.


The default initialization comes from bitter personal 
experience, much like yours!



That gives a totally other meaning to zero cost abstractions 
since in three
weeks of investigation I could have speed-up the program by 
~5%, much more than

the supposed slowdown of variable initialization.


Most of the implicit initializations become dead stores and 
are removed anyway by the optimizer.


Is it even possible to contrive a case where
1) The default initialisation stores are technically dead and
2) Modern compilers can't tell they are dead and elide them and
3) Doing the initialisation has a significant performance impact?

The boring example is extra code causes instruction cache 
misses.


Re: Cleaned up C++

2015-04-22 Thread ketmar via Digitalmars-d
On Wed, 22 Apr 2015 19:32:46 +, weaselcat wrote:

 On Wednesday, 22 April 2015 at 19:29:08 UTC, Walter Bright wrote:
 D is just another of those “Let's put everything on the heap”-languages
 that do then of course need GC.
 
 what's up with people constantly equating garbage collection to being
 the same as java?

they are ignorant, that's it.

signature.asc
Description: PGP signature


Re: Cleaned up C++

2015-04-22 Thread John Colvin via Digitalmars-d
On Wednesday, 22 April 2015 at 21:59:48 UTC, Ola Fosheim Grøstad 
wrote:

On Wednesday, 22 April 2015 at 20:36:12 UTC, John Colvin wrote:

Is it even possible to contrive a case where
1) The default initialisation stores are technically dead and
2) Modern compilers can't tell they are dead and elide them and
3) Doing the initialisation has a significant performance 
impact?


The boring example is extra code causes instruction cache 
misses.


Allocation of large arrays.


That doesn't really answer the question without some more 
context. Can you give a specific example where all 3 points are 
satisfied?


Re: Cleaned up C++

2015-04-22 Thread bearophile via Digitalmars-d

weaselcat:

On Wednesday, 22 April 2015 at 19:29:08 UTC, Walter Bright 
wrote:
D is just another of those “Let's put everything on the 
heap”-languages that do then of course need GC.


what's up with people constantly equating garbage collection to 
being the same as java?


In D you don't put everything on the heap. D is less 
stack-friendly than Ada (and probably Rust too), but in D you 
allocate lot of small stuff on the stack.


Bye,
bearophile


Re: Cleaned up C++

2015-04-22 Thread via Digitalmars-d

On Wednesday, 22 April 2015 at 20:36:12 UTC, John Colvin wrote:

Is it even possible to contrive a case where
1) The default initialisation stores are technically dead and
2) Modern compilers can't tell they are dead and elide them and
3) Doing the initialisation has a significant performance 
impact?


The boring example is extra code causes instruction cache 
misses.


Allocation of large arrays.



Re: Cleaned up C++

2015-04-22 Thread Walter Bright via Digitalmars-d

On 4/22/2015 1:36 PM, John Colvin wrote:

Is it even possible to contrive a case where
1) The default initialisation stores are technically dead and
2) Modern compilers can't tell they are dead and elide them and
3) Doing the initialisation has a significant performance impact?


And you can still initialize with '= void'.



Re: Cleaned up C++

2015-04-22 Thread Walter Bright via Digitalmars-d

On 4/22/2015 2:58 PM, bearophile wrote:

D is less stack-friendly than Ada
(and probably Rust too),


??


Re: Cleaned up C++

2015-04-22 Thread Walter Bright via Digitalmars-d

On 4/22/2015 12:51 PM, ponce wrote:

I didn't appreciate how important default initialization was before having to
fix a non-deterministic, release-only, time-dependent bug in a video encoder
some months ago. Just because of 2 uninitialized variables (C++ doesn't require
member initialization in constructor). If one of them was _exactly equal to 1_
by virtue of randomness, then it would perform from 0 to 2 billions of motion
estimation steps, which is very slow but not a total halt. A watchdog mechanism
would detect this and reboot, hence labelling the bug a deadlock. It would
disappear in debug mode since variables would be initialized then.


The default initialization comes from bitter personal experience, much like 
yours!



That gives a totally other meaning to zero cost abstractions since in three
weeks of investigation I could have speed-up the program by ~5%, much more than
the supposed slowdown of variable initialization.


Most of the implicit initializations become dead stores and are removed anyway 
by the optimizer.




Re: Cleaned up C++

2015-04-22 Thread Adam D. Ruppe via Digitalmars-d

On Wednesday, 22 April 2015 at 22:41:33 UTC, Walter Bright wrote:

And you can still initialize with '= void'.


This was my tip of the week two TWID's ago!
http://arsdnet.net/this-week-in-d/apr-12.html


Re: Cleaned up C++

2015-04-22 Thread Walter Bright via Digitalmars-d

On 4/22/2015 3:52 PM, Adam D. Ruppe wrote:

On Wednesday, 22 April 2015 at 22:41:33 UTC, Walter Bright wrote:

And you can still initialize with '= void'.


This was my tip of the week two TWID's ago!
http://arsdnet.net/this-week-in-d/apr-12.html


Yup!