www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - runtime vs compile-time ref safety: 20% overhead in my example

reply Timothee Cour <thelastmammoth gmail.com> writes:
It has been proposed to introduce runtime bounds checking to insure ref
safety (avoiding escaping references to local variables), enabled with a
-checkboundsref flag (or similar).

I was wondering what would be the cost of doing this, so ran a simple test,
please see:
https://github.com/timotheecour/dtools/blob/master/dtools/scratch/test1.d

(note, I'm not claiming the code is correct (stack could go up or down)
just that any mechanism for runtime ref safety check should bear the same
cost at least).

After running:
ldc2 -release -O2 -run dtools/scratch/test1.d
I get:
reltime=20.7386(%); time(base)=2333 time(t2)=2817

Which means that the extra check to make sure the output reference doesn't
escape a local incurs a 20% cost in my example.

Is there a better implementation (i have a single pointer comparison though
so I'm not sure how that would be optimized) ?

If not, it will mean user will have to choose between enabling runtime
safety checks (20% in my simple example), or throwing away ref safety by
disabling checkboundsref flag.

As an alternative, I have proposed a simple mechanism for safe references
without runtime chesks (http://wiki.dlang.org/DIP38), which will statically
enforce ref safety.
May 25 2013
parent reply Martin Nowak <code dawg.eu> writes:
On 05/26/2013 06:12 AM, Timothee Cour wrote:
 Which means that the extra check to make sure the output reference
 doesn't escape a local incurs a 20% cost in my example.

 Is there a better implementation (i have a single pointer comparison
 though so I'm not sure how that would be optimized) ?

 If not, it will mean user will have to choose between enabling runtime
 safety checks (20% in my simple example), or throwing away ref safety by
 disabling checkboundsref flag.

If you look at the asm output and lower the iteration count, you'll see that you bench llvm's inliner rather than the cost of the runtime check. Also the version that doesn't perform the bounds check doesn't use the ptr parameter, so the variable can be optimized away. In a real implementation computing the frame pointer doesn't incur much cost, it is already available in a register or it is a constant offset from the stack pointer. The branch is easily predictable, as the condition is always the same.
May 26 2013
parent "Mr. Anonymous" <mailnew4ster gmail.com> writes:
On Sunday, 26 May 2013 at 20:23:45 UTC, Martin Nowak wrote:
 On 05/26/2013 06:12 AM, Timothee Cour wrote:
 Which means that the extra check to make sure the output

reference
 doesn't escape a local incurs a 20% cost in my example.

 Is there a better implementation (i have a single pointer

comparison
 though so I'm not sure how that would be optimized) ?

 If not, it will mean user will have to choose between

enabling runtime
 safety checks (20% in my simple example), or throwing away

ref safety by
 disabling checkboundsref flag.

If you look at the asm output and lower the iteration count, you'll see that you bench llvm's inliner rather than the cost of the runtime check. Also the version that doesn't perform the bounds check doesn't use the ptr parameter, so the variable can be optimized away. In a real implementation computing the frame pointer doesn't incur much cost, it is already available in a register or it is a constant offset from the stack pointer. The branch is easily predictable, as the condition is always the same.

I think the solution proposed in the DIP is worth checking, not solely due to performance reasons, but mainly for better safety. A runtime check cannot check all possible code paths when testing, and an undetected bug can surprise you when you don't expect it.
May 26 2013