comp.lang.ada
 help / color / mirror / Atom feed
* How To Pass Large Object Arguments
@ 2013-11-24  7:20 FritzVonBraun
  2013-11-24 11:12 ` Ludovic Brenta
                   ` (4 more replies)
  0 siblings, 5 replies; 7+ messages in thread
From: FritzVonBraun @ 2013-11-24  7:20 UTC (permalink / raw)


Hello all,

I am fairly new to Ada and I am wondering how I should pass large 
parameters to subprograms like arrays or records that contain other 
components like vectors or lists.

I did a lot of reading but wasnt able to find a definite answer. the 
general consensus I got from Barne's book and various blogs and 
whitepapers from Universities was that in theory IN parameters are 
copied but the compiler manufacturer is free to implement a reference to 
the original object and so on. So basically what I found out there is no 
concrete rule that says "parameter of that size or greater are passed by 
reference internally"

So my question is, is there a de facto standard at least? What does Gnat 
do in such cases? (In all honesty, my programs will never run on 
anything but Gnat, so other compilers don't really matter to me). I am 
considering passing objects that I think are too big for a copy 
operation through an access parameter, but that would basically 
contradict the principle of problem orientation instead of machine 
orientation. I would really rather be able to handle these situations 
without having to worry about the underlying mechanism myself.

Thanks for any advice



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: How To Pass Large Object Arguments
  2013-11-24  7:20 How To Pass Large Object Arguments FritzVonBraun
@ 2013-11-24 11:12 ` Ludovic Brenta
  2013-11-24 12:45 ` Peter C. Chapin
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Ludovic Brenta @ 2013-11-24 11:12 UTC (permalink / raw)


FritzVonBraun writes:
> I am fairly new to Ada and I am wondering how I should pass large
> parameters to subprograms like arrays or records that contain other
> components like vectors or lists.

You should not pass parameters by copy or by reference; this is the job
of the compiler.  And you should not presume to know better than the
optimizer in the compiler which method is faster.

So, pass parameters "in" or "in out".

> I did a lot of reading but wasnt able to find a definite answer.

The definitive resource is the Ada Reference Manual (i.e. the ISO
standard that defines the language), which is Free, unlike for some
other languages...

http://www.adaic.org/resources/add_content/standards/12rm/html/RM-6-2.html

GNAT normally passes arrays (including Strings) by reference but very
short arrays might be passed by copy in registers, which is *faster*
than by reference.

HTH

-- 
Ludovic Brenta.


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: How To Pass Large Object Arguments
  2013-11-24  7:20 How To Pass Large Object Arguments FritzVonBraun
  2013-11-24 11:12 ` Ludovic Brenta
@ 2013-11-24 12:45 ` Peter C. Chapin
  2013-11-25 10:59 ` Georg Bauhaus
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Peter C. Chapin @ 2013-11-24 12:45 UTC (permalink / raw)


On Sat, 23 Nov 2013, FritzVonBraun wrote:

> So my question is, is there a de facto standard at least?

Let the compiler worry about it.

You only need to step in if you can show (for example with profiling) that 
your program's performance is inadequate AND the problem is due to a 
"foolish" choice of parameter passing mechanism on the part of the 
compiler.

Certain types are definitely passed by reference, e.g., limited types that 
can't be copied. For types that could be passed either way I think you can 
be confident that any sane compiler will do "the right thing" and pass 
large objects by reference.

Peter



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: How To Pass Large Object Arguments
  2013-11-24  7:20 How To Pass Large Object Arguments FritzVonBraun
  2013-11-24 11:12 ` Ludovic Brenta
  2013-11-24 12:45 ` Peter C. Chapin
@ 2013-11-25 10:59 ` Georg Bauhaus
  2013-11-25 11:09 ` AdaMagica
  2013-11-25 16:53 ` adambeneschan
  4 siblings, 0 replies; 7+ messages in thread
From: Georg Bauhaus @ 2013-11-25 10:59 UTC (permalink / raw)


On 24.11.13 08:20, FritzVonBraun wrote:
> I am considering passing objects that I think are too big for a copy operation through an access parameter, but that would basically contradict the principle of problem orientation instead of machine orientation. I would really rather be able to handle these situations without having to worry about the underlying mechanism myself.

Exactly. The language rules in LRM 6.2 (see Ludovic's message) make
the compiler choose among the possibilities so established. In addition,
some rules are AS-IF rules, so optimizers can manage parameter passing
as they see fit.  They do, drawing upon the compiler writers' knowledge
of the architecture:

If a primitive operation of a "small" tagged type has Inline applied
to it, then, for example, GNAT's optimizer may drop all reference to
the object when translating Object.<primitive operation>.

    function Val (Object : OO_Type) return Some_Integer;
       pragma Inline (Val);


    function Val (Object : in T) return Integer is
    begin
       return Object.Data;
    end Val;

is one example. Its translation, at -gnatn -O2, shows that record
components need not be made publicly visible to address worries
about mechanism.

This feature of the language, i.e. making by-copy/by-reference and in/out
separate concepts, removes the need for access parameters almost everywhere.
And also thinking about them if not problem oriented ;-)

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: How To Pass Large Object Arguments
  2013-11-24  7:20 How To Pass Large Object Arguments FritzVonBraun
                   ` (2 preceding siblings ...)
  2013-11-25 10:59 ` Georg Bauhaus
@ 2013-11-25 11:09 ` AdaMagica
  2013-11-25 16:53 ` adambeneschan
  4 siblings, 0 replies; 7+ messages in thread
From: AdaMagica @ 2013-11-25 11:09 UTC (permalink / raw)


Just to repeat what others have already said in different words:

The decision in Ada to specify the data flow direction rather than the data transfer mechanism was deliberate in order to free the programmer of thinking about this low level feature.

Ada is a high-level language. Trust the compiler to do the correct thing.


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: How To Pass Large Object Arguments
  2013-11-24  7:20 How To Pass Large Object Arguments FritzVonBraun
                   ` (3 preceding siblings ...)
  2013-11-25 11:09 ` AdaMagica
@ 2013-11-25 16:53 ` adambeneschan
  2013-11-25 17:05   ` sbelmont700
  4 siblings, 1 reply; 7+ messages in thread
From: adambeneschan @ 2013-11-25 16:53 UTC (permalink / raw)


On Saturday, November 23, 2013 11:20:53 PM UTC-8, FritzVonBraun wrote:
> Hello all,
> 
> 
> 
> I am fairly new to Ada and I am wondering how I should pass large 
> parameters to subprograms like arrays or records that contain other 
> components like vectors or lists.
> 
> I did a lot of reading but wasnt able to find a definite answer. the 
> general consensus I got from Barne's book and various blogs and 
> whitepapers from Universities was that in theory IN parameters are 
> copied but the compiler manufacturer is free to implement a reference to 
> the original object and so on. So basically what I found out there is no 
> concrete rule that says "parameter of that size or greater are passed by 
> reference internally"
> 
> So my question is, is there a de facto standard at least? What does Gnat 
> do in such cases? (In all honesty, my programs will never run on 
> anything but Gnat, so other compilers don't really matter to me). I am 
> considering passing objects that I think are too big for a copy 
> operation through an access parameter, but that would basically 
> contradict the principle of problem orientation instead of machine 
> orientation. I would really rather be able to handle these situations 
> without having to worry about the underlying mechanism myself.

The RM has some rules about how certain types are to be passed.  Elementary types are always passed by copy; those are types that essentially aren't broken down into subcomponents, i.e. numbers, enumerations, access types.  This is true even for IN OUT parameters; the value will be passed by copy, and a new value will be copied back after the procedure or function returns.  Tagged types, tasks, protected types, other limited types, and any record or array containing one of those, are always passed by reference.  This is true even for IN parameters.  If the "vectors" or "lists" you're referring to are types in one of the Ada.Containers packages, then they will be passed by reference since Ada.Containers.Vectors.Vector is defined to be a tagged type, and I think that's true for all the other containers.

But for records and arrays that don't fall into one of those categories, it's up to the compiler.  And the compiler's decision may depend on the target processor.  One of our compilers (for a particular RISC-ish target) would pass any record up to four 32-bit words by copy, in registers.  However, for a Pentium, which has very few registers, an implementation like this wouldn't make sense, and there's no point in copying a record to the stack if it isn't required by the language.

So for record and array types that aren't specified by the RM, you shouldn't worry about the parameter passing mechanism, and let the compiler decide what it thinks the best way is.  You should also write code in a way that assumes either one or the other mechanism could be used.  That is, if you call Foo(Param => X) where X's type is some record type, and somewhere while Foo is running, something happens that causes a field in X to be modified, Foo itself may or may not notice that that field has changed if it accesses Param.Field.  (And that's true even if X is passed by reference, since the compiler could generate code that "knows" Param.Field won't change, since it can't tell whether the actual record will change behind its back.)  

                                -- Adam


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: How To Pass Large Object Arguments
  2013-11-25 16:53 ` adambeneschan
@ 2013-11-25 17:05   ` sbelmont700
  0 siblings, 0 replies; 7+ messages in thread
From: sbelmont700 @ 2013-11-25 17:05 UTC (permalink / raw)


On Monday, November 25, 2013 11:53:56 AM UTC-5, adambe...@gmail.com wrote:
> Elementary types are always passed by copy

procedure Nit_Picker (x : aliased Integer);



^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2013-11-25 17:05 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-11-24  7:20 How To Pass Large Object Arguments FritzVonBraun
2013-11-24 11:12 ` Ludovic Brenta
2013-11-24 12:45 ` Peter C. Chapin
2013-11-25 10:59 ` Georg Bauhaus
2013-11-25 11:09 ` AdaMagica
2013-11-25 16:53 ` adambeneschan
2013-11-25 17:05   ` sbelmont700

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