comp.lang.ada
 help / color / mirror / Atom feed
From: Keean Schupke <keean.schupke@googlemail.com>
Subject: Re: Efficient Sequential Access to Arrays
Date: Thu, 26 Jul 2012 01:38:41 -0700 (PDT)
Date: 2012-07-26T01:38:41-07:00	[thread overview]
Message-ID: <b18e5dd8-cd07-49df-8011-22e911dc1da0@googlegroups.com> (raw)
In-Reply-To: <juq271$c11$1@munin.nbi.dk>

On Thursday, 26 July 2012 01:15:25 UTC+1, Randy Brukardt  wrote:
> &quot;Keean Schupke&quot; wrote in message 
> &gt; On Wednesday, 25 July 2012 08:09:09 UTC+1, Niklas Holsti  wrote:
> ...
> &gt;&gt; Sure, in general. But here the OP (Keean) is trying to beat the
> &gt;&gt; performance of C++ that uses pointers without index checks. Enabling
> &gt;&gt; index checks in the Ada code would probably (in this case, where the
> &gt;&gt; algorithm has scatterered indexing of the array) slow it by an amount
> &gt;&gt; that swamps the effect of the multiplication optimization.
> &gt;
> &gt; On the specific point of array index checking, if you can statically prove 
> &gt; the algorithm
> &gt; using the array will never use an out of range index, there is no need to 
> &gt; run-time index check.
> &gt;
> &gt; If we generate a random number between one and N, and then lookup the Nth 
> &gt; element, we do not
> &gt; need to range check as the number is by definition in range. If the type 
> &gt; system can carry such proofs
> &gt; (for example using range types in Ada) so you have:
> &gt;
> &gt; subtype Idx is Integer range 1 .. 10;
> &gt; type Arr is array (Idx) of Integer;
> &gt; function Random returns Idx;
> &gt; A : Arr;
> &gt; A(Random); -- as the random number is already in the range there needs to 
> &gt; be no
> &gt;                         range checks on the array lookup.
> 
> This isn&#39;t necessarily true. The following is *very* Ada language-lawyer, so 
> skip if you don&#39;t want to know the details. (BTW, this is all Ada 95 
> thinking, refined somewhat since.)
> 
> Ada scalar objects can be in a state known as &quot;invalid&quot; (see 13.9.1 in your 
> Ada Reference Manual). For integer types, this corresponds to a value out of 
> range. Ada compilers are always allowed to return invalid results from 
> scalar operations, with a few exceptions. So in general, an Ada compiler 
> does not actually need to make range checks on scalar objects. The only time 
> that a check on a scalar object *has* to be performed is when using the 
> value could lead to erroneous execution (such as in indexing out of range).

This is an equivalent concept to nullable, so two questions:

What is the literal for 'invalid', IE:

X : Index := #INVALID -- we should be able to initialise to invalid.

if X = #INVALID -- I want to be able to test for invalid.


> 
> So, formally, writing a scalar subtype does not ensure that a compiler can 
> eliminate checks. Indeed, it doesn&#39;t necessarily mean anything at all, as 
> scalar objects can be uninitialized and the compiler has to assume that they 
> could be out of range unless it can prove that they are initialized on all 
> paths.

Like not null we therefore need:

type X_Type is new Integer not invalid range 0 .. 10;
X : X_Type; -- error
X : X_Type := 0; -- OK

> 
> Of course, us compiler implementers *want* to eliminate checks based in 
> subtypes. There are various strategies for doing so. The &quot;usual&quot; one is that 
> the compiler defines some subtest of scalar objects as &quot;known to be valid&quot;. 
> Those are objects that the compiler can easily prove are initialized. (For 
> Janus/Ada, we use a fairly conservative definition: stand-alone objects that 
> are explicitly initialized, literals, loop parameters, and subprogram 
> parameters. I don&#39;t remember if function results are included or not.). 
> Checks have to be performed on assignments and other operations on &quot;known to 
> be valid&quot; objects (array indexing is also treated this way) unless subtypes 
> are the same or statically compatible AND all constituents of the source 
> expression are &quot;known to be valid&quot;.

The above helps the compiler eliminate range checks, the other is type promotion: for example:

X : not invalid Integer := 99;
Y : array (10 .. 1000) of Integer;

if X <= 1000 then
   -- type of X is now : not invalid Integer range Integer'First .. 1000;
   if X >= 10 then
       -- type of X is now : not invalid Integer range 10 .. 1000;
       Y(X) -- No need for any range checks.
   end if;
end if;

> 
> Our optimizer can remove a few checks that have been generated because of 
> later flow analysis and the like, but what can be done then is quite 
> limited. Generally, the compiler has to not generate the checks in the first 
> place.

See above for language changes to facilitate better range check removal.

> 
> I&#39;m not sure precisely how GNAT handles this, but elimination of checks is 
> *much* harder than it appears on the surface, mainly because Ada allows 
> uninitialized objects (and still expects uses of them to be detected).

This is something I have looked at in a couple of different contexts, and using dependent types (a simple example of which is above) there are known techniques for removing all implicit range checks. Personally I dont like implicit stuff, so for me personally I would like the compiler to never insert implicit checks but instead issue a compile error if it ever had to insert an implicit range check. As above you may have to insert explicit range checks to satisfy the compiler, or you may used an unchecked conversion to tell the compiler, trust me, i know what I am doing and I have verified the code will not generate out of bounds values due to unit testing and formal verification methods.

> 
> &gt; I don&#39;t know how good the compiler is at doing this?
> 
> If the implementation model is &quot;wrong&quot;, it might not do it at all.
> 
> &gt; There are times when the programmer can guarantee that the output of a 
> &gt; function will be
> &gt; within range due to extensive unit testing and validation.
> 
> But that doesn&#39;t guarantee that the compiler can remove the checks.

The compiler should remove the range checks if the programmer is telling it that the value is definitely within range. With a 'not invalid' type modifier, this can be done with some kind of unchecked conversion.

> 
> &gt; I wonder, is there a way to get the compiler (GNAT) to issue a warning 
> &gt; when it has to insert a range check?
> 
> Can&#39;t say if there is a GNAT option, but it seems like a good idea. I added 
> such an &quot;information&quot; (it&#39;s not a warning in the sense that normally it 
> doesn&#39;t need to be corrected) to the (lengthy) to-do list for Janus/Ada.
> 
>                                         Randy.

Cheers,
Keean.



  reply	other threads:[~2012-07-26  8:47 UTC|newest]

Thread overview: 88+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-07-15 18:40 Efficient Sequential Access to Arrays Keean Schupke
2012-07-15 19:48 ` Dmitry A. Kazakov
2012-07-15 20:03   ` Keean Schupke
2012-07-15 20:56     ` Keean Schupke
2012-07-16 11:34       ` Jacob Sparre Andersen
2012-07-15 21:05     ` tmoran
2012-07-15 21:08       ` Keean Schupke
2012-07-16  1:19         ` tmoran
2012-07-15 21:44     ` Georg Bauhaus
2012-07-16  7:47     ` Dmitry A. Kazakov
2012-07-16 10:16       ` Keean Schupke
2012-07-16 14:57         ` Dmitry A. Kazakov
2012-07-16 16:39           ` Keean Schupke
2012-07-16 17:02             ` Georg Bauhaus
2012-07-16 18:48             ` Dmitry A. Kazakov
2012-07-16 19:12               ` Keean Schupke
2012-07-17  6:31                 ` Dmitry A. Kazakov
2012-07-17  6:50                   ` Georg Bauhaus
2012-07-17  8:42                     ` Dmitry A. Kazakov
2012-07-17  7:24                   ` Keean Schupke
2012-07-16 19:43             ` John B. Matthews
2012-07-16 20:44               ` Keean Schupke
2012-07-16 22:23             ` tmoran
2012-07-17  6:40               ` Keean Schupke
2012-07-17  9:01                 ` Dmitry A. Kazakov
2012-07-18  8:10                   ` Keean Schupke
2012-07-18 18:11                     ` tmoran
2012-07-19 10:41                       ` Keean Schupke
2012-07-19 11:18                         ` Georg Bauhaus
2012-07-19 19:58                           ` Keean Schupke
2012-07-21  8:24                             ` Keean Schupke
2012-07-21 11:52                               ` Georg Bauhaus
2012-07-21 16:14                                 ` Keean Schupke
2012-07-21 17:09                                   ` Keean Schupke
     [not found]                                   ` <i78m081tccmp078spmsei1l5vnj3k0kbkj@invalid.netcom.com>
2012-07-22 15:50                                     ` Keean Schupke
2012-07-22  5:13                               ` Shark8
2012-07-15 21:35   ` J-P. Rosen
2012-07-15 19:52 ` Shark8
2012-07-15 20:16   ` Keean Schupke
2012-07-15 21:33     ` Georg Bauhaus
2012-07-17 18:16 ` Florian Weimer
2012-07-22 10:01 ` robin.vowels
2012-07-30  6:31   ` Jacob Sparre Andersen
2012-07-30  7:16     ` Keean Schupke
2012-07-30  9:20     ` Georg Bauhaus
2012-07-30 14:04       ` Keean Schupke
2012-07-22 10:09 ` robin.vowels
2012-07-22 16:02   ` Keean Schupke
2012-07-22 16:21 ` Florian Weimer
2012-07-22 16:46   ` Keean Schupke
2012-07-22 18:41     ` Florian Weimer
2012-07-24  8:21       ` Keean Schupke
2012-07-22 17:34   ` Niklas Holsti
2012-07-22 18:21     ` Keean Schupke
2012-07-30 14:18       ` Jacob Sparre Andersen
2012-07-24 16:00     ` robin.vowels
2012-07-25  7:09       ` Niklas Holsti
2012-07-25  9:03         ` Keean Schupke
2012-07-26  0:15           ` Randy Brukardt
2012-07-26  8:38             ` Keean Schupke [this message]
2012-07-26 10:10               ` Brian Drummond
2012-07-26 12:32                 ` Keean Schupke
2012-07-26 13:46                   ` Dmitry A. Kazakov
2012-07-26 17:40                     ` Shark8
2012-07-26 18:56                       ` Dmitry A. Kazakov
2012-07-27  5:25                         ` Shark8
2012-07-27  6:28                           ` Dmitry A. Kazakov
2012-07-27  7:01                             ` Vasiliy Molostov
2012-07-27  8:48                               ` Dmitry A. Kazakov
2012-07-27 12:01                                 ` Georg Bauhaus
2012-07-27 16:49                                 ` Vasiliy Molostov
2012-07-27 19:38                                   ` Dmitry A. Kazakov
2012-07-28  5:32                             ` Shark8
2012-07-28  7:37                               ` Dmitry A. Kazakov
2012-07-28 18:32                                 ` Shark8
     [not found]                     ` <6ov218tnkbqu3vpkuo4t77rd7de0a3aesf@invalid.netcom.com>
2012-07-26 18:49                       ` Dmitry A. Kazakov
     [not found]                         ` <86d31898ne39maimbl24knds7rf38qg7vc@invalid.netcom.com>
2012-07-27  6:45                           ` Dmitry A. Kazakov
2012-07-27  8:21                   ` Keean Schupke
2012-07-27  8:50                     ` Dmitry A. Kazakov
2012-07-27  9:17                       ` Keean Schupke
2013-02-25 21:18                     ` Eryndlia Mavourneen
2012-07-26 13:08               ` Georg Bauhaus
2012-07-26 19:37                 ` stefan-lucks
2012-07-26 19:21               ` stefan-lucks
2012-07-31  3:12               ` Randy Brukardt
2012-07-26  7:11           ` Markus Schöpflin
2012-07-26 14:47         ` Robin Vowels
2012-07-26 15:18           ` Martin
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox