Home > Archive > APL > October 2007 > Re: APL2007 update -> Sorting
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Re: APL2007 update -> Sorting
|
|
| Jeff Reid 2007-10-08, 9:58 pm |
| >>>> After my long post, consider the fact that it took less than 1
>
> isn't that a bit of a sweeping statement?
In the case of C and C++, pointers are used for every instance of
an object allocated via malloc or new. If code uses an index for
an allocated object, then this consumes two cpu registers, but using
a pointer reduces this to just consumption of a single cpu register,
so there is an advantage to using pointers.
| |
| Greg Lindahl 2007-10-08, 9:58 pm |
| In article <JSBOi.1263$DP1.1209@newsfe11.phx>,
Jeff Reid <jeffareid@hotmail.com> wrote:
>In the case of C and C++, pointers are used for every instance of
>an object allocated via malloc or new. If code uses an index for
>an allocated object, then this consumes two cpu registers, but using
>a pointer reduces this to just consumption of a single cpu register,
>so there is an advantage to using pointers.
This is definitely not true when you're using an optimizing
compiler. It's pretty much not true when you aren't, too.
-- greg
| |
| Paul Houle 2007-10-09, 3:58 am |
|
"Greg Lindahl" <lindahl@pbm.com> wrote in message
news:470aecce$1@news.meer.net...
> In article <JSBOi.1263$DP1.1209@newsfe11.phx>,
> Jeff Reid <jeffareid@hotmail.com> wrote:
>
>
> This is definitely not true when you're using an optimizing
> compiler. It's pretty much not true when you aren't, too.
>
> -- greg
It is true, Greg. Unless an object is statically allocated, efficiently
dereferencing
a "pointer" in the form of an index will require the use of two CPU
registers in any
modern architecture. Think about it; write yourself some assembly sequences
to
do it. And less available registers degrades the ability of any compiler to
generate
fast code, optimizing or not.
....Paul
| |
| Greg Lindahl 2007-10-09, 3:58 am |
| In article <bSEOi.40226$RX.25917@newssvr11.news.prodigy.net>,
Paul Houle <asmguru@yahoo.com> wrote:
>It is true, Greg. Unless an object is statically allocated, efficiently
>dereferencing
>a "pointer" in the form of an index will require the use of two CPU
>registers in any
>modern architecture.
You might want to to examine the code actually generated by compilers.
In a loop, for example, you will be hard-pressed to find any
optimizing compiler that uses 2 registers.
-- greg
| |
| Paul Houle 2007-10-09, 3:58 am |
|
"Greg Lindahl" <lindahl@pbm.com> wrote in message
news:470b23b8$1@news.meer.net...
> In article <bSEOi.40226$RX.25917@newssvr11.news.prodigy.net>,
> Paul Houle <asmguru@yahoo.com> wrote:
>
>
> You might want to to examine the code actually generated by compilers.
> In a loop, for example, you will be hard-pressed to find any
> optimizing compiler that uses 2 registers.
>
> -- greg
>
Oh, now we're in a loop are we? I guess you imagine it to
be a tight one, where not many registers are needed?
I suppose your indexes are pre-shifted per the operand width?
And maybe they've had the base-array-address added to
them as well..... (oh wait, then they'd be... pointers)
I have examined code generated by compilers, hundreds of
times, on multiple architectures, over a few decades.
The structure of a complex memory reference these days is
offset[basereg+indexreg*scale]
Where offset is a constant, and scale a constant small power
of two. Note the use of 'basereg' and 'indexreg' where there
is both array-start-pointer and index. It takes two registers.
When using a pointer alone, the memory reference will be
simply [pointer] -- one register.
Sure, you could use one register in the base/index case, by
shifting the index and adding the base pointer directly to the
index from memory, but that is abysmally slow in comparison.
It's not rocket science. When you have two components
(array-base-pointer and index) it takes more registers --
even if one is initialized just once outside a loop --
to address a target operand than if you are given a pointer
directly to it. The loss of register space does negatively
impact the speed of machine code to implement an
algorithm of even moderate complexity. Especially on a
register-limited architecture like the X86 (prior to the 64-bit
extensions).
....Paul
| |
| glen herrmannsfeldt 2007-10-09, 7:57 am |
| Greg Lindahl wrote:
> In article <JSBOi.1263$DP1.1209@newsfe11.phx>,
> Jeff Reid <jeffareid@hotmail.com> wrote:
[color=darkred]
> This is definitely not true when you're using an optimizing
> compiler. It's pretty much not true when you aren't, too.
Both compilers and machines have changed over the years.
On register starved hardware, such as x86, it may still be
true. Often, though, the compiler can figure it out.
If you are comparing C code such as:
s=a;
for(i=0;i<n;i++) *s++=i;
to
for(i=0;i<n;i++) a[i]=i;
note that the index is already in a register. Many systems
can directly index with that register. In others, the compiler
will figure it out and generate the appropriate pointer
incrementing code. Compilers have been able to optimize
this one at least since the OS/360 Fortran H compiler.
(This is similar to one of the examples given.)
-- glen
| |
| Greg Lindahl 2007-10-09, 6:58 pm |
| In article <RqGOi.5328$4V6.4025@newssvr14.news.prodigy.net>,
Paul Houle <asmguru@yahoo.com> wrote:
>I have examined code generated by compilers, hundreds of
>times, on multiple architectures, over a few decades.
Great. Then why are you making sweeping generalizations which are
incorrect?
From reading your latest note, it seems that when you say "pointer"
you may be intending to mean an address register, not a high-level
language pointer. That would explain why you're making no sense. I've
never seen anyone us "pointer" like that before.
-- greg
| |
| Greg Lindahl 2007-10-09, 6:58 pm |
| In article <RqGOi.5328$4V6.4025@newssvr14.news.prodigy.net>,
Paul Houle <asmguru@yahoo.com> wrote:
>I have examined code generated by compilers, hundreds of
>times, on multiple architectures, over a few decades.
Great. Then why are you making sweeping generalizations which are
incorrect?
From reading your latest note, it seems that when you say "pointer"
you may be intending to mean an address register, not a high-level
language pointer. That would explain why you're making no sense. I've
never seen anyone us "pointer" like that before.
-- greg
| |
| Jeff Reid 2007-10-09, 6:58 pm |
| >>In the case of C and C++, pointers are used for every instance of
>
> This is definitely not true when you're using an optimizing
> compiler. It's pretty much not true when you aren't, too.
So I'll modify my statement, to read "If code uses an index for an
allocated object, then this may consume two cpu registers, but using
a pointer will always use just a single cpu register."
A better example would be the actual case I used in my sort program.
In this case there are three main pointers used to point to arrays
of pointers to records, and two more used to point to arrays of group
counts. If the compiler runs out of registers during optimization,
then the original pointer(s) for the allocated memory can be left on
the stack, leaving the 5 working pointers in registers. If these
5 working pointers were replaced by 5 working indexes, there's no
guarantee that the compiler will optmized all of the index references
back into pointers and eliminate referencing the original pointer(s)
for the allocated memory.
> Not other than issues of style, maintainability, and the usual
> discouragement of pointers where possible.
Regardless of the compiler generated code, why the objection to using
pointers in the first place?
| |
| Jeff Reid 2007-10-09, 6:58 pm |
| >> You might want to to examine the code actually generated by compilers.
[color=darkred]
> Oh, now we're in a loop are we? I guess you imagine it to
> be a tight one, where not many registers are needed?
> I suppose your indexes are pre-shifted per the operand width?
> And maybe they've had the base-array-address added to
> them as well..... (oh wait, then they'd be... pointers)
I think what Greg is getting at occurs in small loops:
With Microsoft Visual Studio both these very tight loops generate the
exact same code, using a single pointer:
unsigned char *p = pMem;
while(*p++);
unsigned int i = 0;
i = 0;
while(pMem[i++]);
I'm not sure if the compiler is smart enough to convert all index operations
into their pointer equivalents, and rather than worry about if the compiler
will be able to make these optimizations, I will use pointers when I feel
that pointers are a better coding method than indexing.
Which brings me back to the question, what is undesirable about using pointers
in the first place, regardless of compiler optimizations?
| |
| glen herrmannsfeldt 2007-10-09, 6:58 pm |
| Jeff Reid wrote:
(snip)
> I'm not sure if the compiler is smart enough to convert all index operations
> into their pointer equivalents, and rather than worry about if the compiler
> will be able to make these optimizations, I will use pointers when I feel
> that pointers are a better coding method than indexing.
The general rule on hand optimizing still applies.
Unless it is known or believed to be limiting the speed, write the
code that is more readable.
> Which brings me back to the question, what is undesirable about using pointers
> in the first place, regardless of compiler optimizations?
There are still enough people who believe the speed difference
makes it worth extra work to write loops using pointers. If it is
natural to write using pointers, then do it. If not, and it isn't
in a time critical part, likely deeply nested loops, then indexing
should be fine.
-- glen
| |
| Gary Scott 2007-10-09, 9:57 pm |
| Jeff Reid wrote:
>
>
> So I'll modify my statement, to read "If code uses an index for an
> allocated object, then this may consume two cpu registers, but using
> a pointer will always use just a single cpu register."
>
> A better example would be the actual case I used in my sort program.
> In this case there are three main pointers used to point to arrays
> of pointers to records, and two more used to point to arrays of group
> counts. If the compiler runs out of registers during optimization,
> then the original pointer(s) for the allocated memory can be left on
> the stack, leaving the 5 working pointers in registers. If these
> 5 working pointers were replaced by 5 working indexes, there's no
> guarantee that the compiler will optmized all of the index references
> back into pointers and eliminate referencing the original pointer(s)
> for the allocated memory.
>
>
>
>
> Regardless of the compiler generated code, why the objection to using
> pointers in the first place?
>
>
In the most general sense, pointers are considered to be "low level"
constructs and error prone (a significant and common source of
programmer error). You will note that it says "where possible".
>
>
>
--
Gary Scott
mailto:garylscott@sbcglobal dot net
Fortran Library: http://www.fortranlib.com
Support the Original G95 Project: http://www.g95.org
-OR-
Support the GNU GFortran Project: http://gcc.gnu.org/fortran/index.html
If you want to do the impossible, don't hire an expert because he knows
it can't be done.
-- Henry Ford
| |
| Walter Spector 2007-10-09, 9:57 pm |
| Jeff Reid wrote:
> Which brings me back to the question, what is undesirable about using pointers
> in the first place, regardless of compiler optimizations?
Unrestricted pointers cause optimization problems due primarily to aliasing
potential:
http://en.wikipedia.org/wiki/Aliasing_(computing)
Then there are the many opportunities for memory leakage, bad addresses,
buffer overruns, portability issues, etc. Some consider pointers as bad as,
or even worse than, GOTO statements.
OTOH, in some languages they are a way to Get Things Done in a way not
otherwise possible.
W.
| |
| Jeff Reid 2007-10-09, 9:57 pm |
| > There are still enough people who believe the speed difference
> makes it worth extra work to write loops using pointers.
Well since this is how compilers optimize the of indexes in some
case, the compiler writers thought it was worth it.
I guess one issue is how the loop is terminated. If it's a fixed count,
then an end pointer can be used instead of an counter:
for(p = array, pEnd = array+count; p < pEnd; p++){...}
or in this case an index could be used:
for(i = 0; i < count; i++){ ... array[i] ...}
For these two examples, there's no clear advantage of one versus the other,
and I would probably follow the trend in adajcent code. If a function
is being called in the loop, you get:
for(p = array, pEnd = array+count; p < pEnd; p++){... function(p) ...}
for(i = 0; i < count; i++){ ... function(&array[i]) ...}
and maybe in this case I might have a slight preference for the pointer.
> If it is natural to write using pointers, then do it. ... else don't
That seems reasonable.
| |
| Paul Houle 2007-10-09, 9:57 pm |
|
"Jeff Reid" <jeffareid@hotmail.com> wrote in message
news:GeSOi.228754$zz2.124940@newsfe12.phx...
> I think what Greg is getting at occurs in small loops:
>
> With Microsoft Visual Studio both these very tight loops generate the
> exact same code, using a single pointer:
>
> unsigned char *p = pMem;
> while(*p++);
>
> unsigned int i = 0;
> i = 0;
> while(pMem[i++]);
>
> I'm not sure if the compiler is smart enough to convert all index
> operations
> into their pointer equivalents, and rather than worry about if the
> compiler
> will be able to make these optimizations...
Given multiple indexes that one is using in an unpredictable way --
e.g. sorting what they index -- there is no way for a compiler to
"convert all index operations into their pointer equivalents."
No matter how smart it is....
Dereferencing a random index in an efficient manner requires the
use of an additional register (in comparison to a pointer). That can
have a negative effect on code speed due to register shortage.
That was the topic I was addressing, and the point that you (Jeff)
originally made.
....Paul
| |
| Jeff Reid 2007-10-10, 3:57 am |
|
> Given multiple indexes that one is using in an unpredictable way --
> e.g. sorting what they index -- there is no way for a compiler to
> "convert all index operations into their pointer equivalents."
> No matter how smart it is....
>
> That was the topic I was addressing, and the point that you (Jeff)
> originally made.
Agreed, which is why I stated
[color=darkred]
| |
| glen herrmannsfeldt 2007-10-10, 3:57 am |
| Jeff Reid wrote:
[color=darkred]
> Well since this is how compilers optimize the of indexes in some
> case, the compiler writers thought it was worth it.
"We should forget about small efficiencies, say about 97% of the time:
premature optimization is the root of all evil." (Knuth, Donald.
Structured Programming with go to Statements, ACM Journal Computing
Surveys, Vol 6, No. 4, Dec. 1974. p.268.)
http://en.wikipedia.org/wiki/Optimization_(computer_science)
> I guess one issue is how the loop is terminated. If it's a fixed count,
> then an end pointer can be used instead of an counter:
> for(p = array, pEnd = array+count; p < pEnd; p++){...}
> or in this case an index could be used:
> for(i = 0; i < count; i++){ ... array[i] ...}
> For these two examples, there's no clear advantage of one versus the other,
> and I would probably follow the trend in adajcent code. If a function
> is being called in the loop, you get:
> for(p = array, pEnd = array+count; p < pEnd; p++){... function(p) ...}
> for(i = 0; i < count; i++){ ... function(&array[i]) ...}
Many machines have special instructions for doing loops.
In this case, the compiler may or may not be able to use those
instructions, or may not figure it out, in the first case.
Some have the ability to multiply an index register by the size of
the item being indexed. Others will rescale the loop variable by the
appropriate size, if the value of the loop variable isn't used
otherwise. Newer machines have more registers than older ones,
making register allocation less of a problem.
> and maybe in this case I might have a slight preference for the pointer.
[color=darkred]
> That seems reasonable.
-- glen
| |
| Jeff Reid 2007-10-10, 3:57 am |
| >> Which brings me back to the question, what is undesirable about using pointers
>
> Unrestricted pointers cause optimization problems due primarily to aliasing
> potential:
Don't compilers still have options to indicate aliasing isn't occurring?
> Then there are the many opportunities for memory leakage, bad addresses,
> buffer overruns, portability issues, etc.
Indexing doesn't solve these problems. Memory leakage can't be solved
with indexing. Bad addresses and buffer overrruns can occur if indexes
are bad. As for portability issues, I don't see an issue with pointers.
Note that one of the main concepts of C++ is creating (allocating)
instances of objects, which requires pointers.
> Some consider pointers as bad as, or even worse than, GOTO statements.
Well I'm not anti "goto" either, and use them when I think it makes the
code more readable, rather than inventing ways to get around them.
The classic case for "goto", try duplicating this with if statements and
see how readable the code is.
if(step1()) // non-zero return means failure
{
handlestep1failure();
goto fail;
}
if(step2())
{
handlestep2failure();
goto fail;
}
if(step3())
{
handlestep3failure();
goto fail;
}
... // main line code
return(0);
fail: // error handling code
...
return(1);
| |
| Jeff Reid 2007-10-10, 3:57 am |
| >> Regardless of the compiler generated code, why the objection to using
[color=darkred]
> In the most general sense, pointers are considered to be "low level" constructs and error prone (a significant and
> common source of programmer error). You will note that it says "where possible".
Yet pointers are the only means of dealing with dynamic instances of
objects in C++ (or allocated objects in C). It's also the norm to use
pointers to instances of objects instead of having global objects when
passing arguments to functions. I wouldn't consider this "low level".
So the real argument here is how to handle an array of objects, via a
second pointer or an index, for example, ptr->element or array[i].element.
As previously mentioned, if the compiler doesn't optimize array[i].element
into ptr->element, then the code has used up an extra register or memory
reference, since it needs both "array" and "i". When calling a function,
is function(&array[i]) really better than function(ptr)?
| |
| Walter Spector 2007-10-10, 3:57 am |
| Jeff Reid wrote:
>
> Don't compilers still have options to indicate aliasing isn't occurring?
Sometimes yes, sometimes no. And even if they do, most programmers never
use them.
>
> Indexing doesn't solve these problems. Memory leakage can't be solved
> with indexing. Bad addresses and buffer overrruns can occur if indexes
> are bad.
Except that a compiler can generate code to check for such things
when arrays are defined as arrays vs raw C-like pointer dereferences.
Note that Fortran-90 pointers work quite differently than C-style
pointers. Much more information is carried in the descriptor, so more
checking is possible. Though aliasing problems remain.
> As for portability issues, I don't see an issue with pointers.
"All the worlds a VAX"...
> Note that one of the main concepts of C++ is creating (allocating)
> instances of objects, which requires pointers.
A number of languages allow object creation without using user-visible
pointers.
>
> Well I'm not anti "goto" either, and use them when I think it makes the
> code more readable, rather than inventing ways to get around them.
>
> The classic case for "goto", try duplicating this with if statements and
> see how readable the code is...
> [example deleted]
Your example cries for a structured exception handling construct
such as try/throw/catch.
W.
| |
| glen herrmannsfeldt 2007-10-10, 3:57 am |
| Walter Spector wrote:
(snip)
> Except that a compiler can generate code to check for such things
> when arrays are defined as arrays vs raw C-like pointer dereferences.
> Note that Fortran-90 pointers work quite differently than C-style
> pointers. Much more information is carried in the descriptor, so more
> checking is possible. Though aliasing problems remain.
C doesn't require raw pointers, but that is the common implementation.
-- glen
| |
| Walter Spector 2007-10-10, 3:57 am |
| glen herrmannsfeldt wrote:
> C doesn't require raw pointers, but that is the common implementation.
When a compiler sees a declaration like:
int *p;
What assumptions can be made as far as bounds checking? Can the
size of the eventual malloc be passed into the pointer?
W.
| |
| Jeff Reid 2007-10-10, 3:57 am |
| >> C doesn't require raw pointers, but that is the common implementation.
>
> When a compiler sees a declaration like:
> int *p;
That's why there is C++:
int * p = new int [0x10000];
It would have to be smart to handle pointer assignments:
int * q = p + 1024;
Note that the C++ Standard Template Library for <vector> uses "random
access iterators", which are pointers restricted to a specific instance
of a <vector> when assigned. In debug builds, the pointers are checked
for validity.
std::vector <int> v0(0x1000);
std::vector <int> v1(0x1000);
std::vector <int> :: iterator pv;
pv = v0.begin(); // or pv = &v0[0];
...
pv = v1.begin(); // or pv = &v1[0];
A normal pointer can also be used, but I doubt it's checked:
int * pi = &v0[0];
Getting back on this sub-topic about sorting, note that the Microsoft
sort routines sort() and stable_sort() operate on <vector>. My purpose
in creating this sub-thread was to compare sort algorithms, which got
a bit off topic with the index versus pointer stuff. Both the Microsoft
and my sort routines use pointers, the Microsoft ones use the vector
iterators, while I used pointers because I simply converted existing
code and didn't bother to change to the vector iterators. When building
in "release" mode, I didn't see any bounds checking on the iterators,
so they're essentially just pointers.
On yet another side note, note that the standard template library is
not a library, but instead source code that gets compiled along with the
user code. This allows for compile time optimization for STL objects.
For example, a <vector> could be a vector of structures, and iterators
could be iterators to structures, and usage would be optimized at
compile time.
| |
| glen herrmannsfeldt 2007-10-10, 3:57 am |
| Walter Spector wrote:
> glen herrmannsfeldt wrote:
[color=darkred]
> When a compiler sees a declaration like:
> int *p;
> What assumptions can be made as far as bounds checking? Can the
> size of the eventual malloc be passed into the pointer?
The language allows for it, but it is rarely implemented that way.
A pointer could be implemented as an origin, length, and current
offset. Pointer arithmetic would change the offset. Dereferencing
would test the current offset against the length, and if valid load
or store as appropriate.
-- glen
| |
| Walter Spector 2007-10-10, 6:58 pm |
| Jeff Reid wrote:
>
> That's why there is C++:
>
> int * p = new int [0x10000];
This is essentially identical to the C/malloc case.
> Note that the C++ Standard Template Library for <vector> uses "random
> access iterators", which are pointers restricted to a specific instance
> of a <vector> when assigned. In debug builds, the pointers are checked
> for validity.
If you are going to drag the STL into the discussion, many more
factors come into play. Yes, by using <vector> you can get better
error checking when needed. But then, there is more than a simple
raw pointer under the hood.
> Getting back on this sub-topic about sorting, note that the Microsoft
> sort routines sort() and stable_sort() operate on <vector>...
These are the routines in <algorithms>. IME, they are pretty good.
> On yet another side note, note that the standard template library is
> not a library, but instead source code that gets compiled along with the
> user code. This allows for compile time optimization for STL objects.
Yup. Much better than qsort(3c) for this very reason.
W.
| |
| Greg Lindahl 2007-10-10, 6:58 pm |
| In article <r2SOi.122761$xZ2.101369@newsfe10.phx>,
Jeff Reid <jeffareid@hotmail.com> wrote:
>So I'll modify my statement, to read "If code uses an index for an
>allocated object, then this may consume two cpu registers, but using
>a pointer will always use just a single cpu register."
That's more correct, but not really useful for giving optimization
advice.
>Regardless of the compiler generated code, why the objection to using
>pointers in the first place?
The least maintainable and hardest to optimize C code I've worked with
was written by programmers who think that using pointers everywhere
aids efficiency. The optimization issues center on aliasing problems.
In Fortran, the convention is to minimize use of pointers, and the
language has a first-class allocatable array type to handle the
case of simply wanting an array of variable size.
-- greg
| |
|
| In article <LIXOi.14494$054.1557@newsfe14.phx>,
Jeff Reid <jeffareid@hotmail.com> wrote:
>Indexing doesn't solve these problems. Memory leakage can't be solved
>with indexing. Bad addresses and buffer overrruns can occur if indexes
>are bad. As for portability issues, I don't see an issue with pointers.
It's easy to check indexes to see if they're within the bounds of the
array. Pointers are not inherently limited to a specific array, so
you can't (easily) check if one is randomly wandering around
(allocated) memory.
>The classic case for "goto", try duplicating this with if statements and
>see how readable the code is.
>
> if(step1()) // non-zero return means failure
> {
> handlestep1failure();
> goto fail;
> }
> if(step2())
> {
> handlestep2failure();
> goto fail;
> }
> if(step3())
> {
> handlestep3failure();
> goto fail;
> }
> ... // main line code
> return(0);
>
>fail: // error handling code
> ...
> return(1);
ok: TRUE
if(step1()
{
handlestep1failure();
ok: 0;
}
if(ok&&step2())
.. . .
Seth
| |
| Greg Lindahl 2007-10-10, 6:58 pm |
| In article <fejens$1nj$1@reader1.panix.com>, Seth <sethb@panix.com> wrote:
>It's easy to check indexes to see if they're within the bounds of the
>array. Pointers are not inherently limited to a specific array, so
>you can't (easily) check if one is randomly wandering around
>(allocated) memory.
You're cross-posting to comp.lang.fortran. Fortran has a restricted
kind of pointer which has some properties considerably different from,
say, C pointers. And actually there are some debugging C
implementations which do have a base and bound associated with all
pointers.
-- greg
| |
| Greg Lindahl 2007-10-10, 6:58 pm |
| In article <fejens$1nj$1@reader1.panix.com>, Seth <sethb@panix.com> wrote:
>It's easy to check indexes to see if they're within the bounds of the
>array. Pointers are not inherently limited to a specific array, so
>you can't (easily) check if one is randomly wandering around
>(allocated) memory.
You're cross-posting to comp.lang.fortran. Fortran has a restricted
kind of pointer which has some properties considerably different from,
say, C pointers. And actually there are some debugging C
implementations which do have a base and bound associated with all
pointers.
-- greg
| |
| Jan Vorbrüggen 2007-10-12, 7:57 am |
| > I'm not sure if the compiler is smart enough to convert all index operations
> into their pointer equivalents,
The VAX compilers were already very smart about this a quarter of a century
ago, even for multidimensional array accesses. THere is no reason to believe
that current compilers should be worse. Only language semantics are likely to
get in their way (e.g., aliasing rules or non-rules).
Jan
| |
| Jan Vorbrüggen 2007-10-12, 7:57 am |
| > Yet pointers are the only means of dealing with dynamic instances of
> objects in C++ (or allocated objects in C).
Certainly, unrestricted pointers are not needed for the purpose - see, for
instance, Fortran's ALLOCATABLEs.
Jan
| |
| glen herrmannsfeldt 2007-10-12, 7:57 am |
| Jan Vorbrüggen wrote:
[color=darkred]
> The VAX compilers were already very smart about this a quarter of a
> century ago, even for multidimensional array accesses. THere is no
> reason to believe that current compilers should be worse. Only language
> semantics are likely to get in their way (e.g., aliasing rules or
> non-rules).
VAX has indexing instructions that index in units of the
operand size. That helps when you have a loop variable
incrementing by one, so there is no registers advantage
for pointers.
-- glen
| |
| Jan Vorbrüggen 2007-10-12, 7:57 am |
| >> The VAX compilers were already very smart about this a quarter of a
>
> VAX has indexing instructions that index in units of the
> operand size. That helps when you have a loop variable
> incrementing by one, so there is no registers advantage
> for pointers.
The whole point of the VAX - in particular, Fortran and Pascal - compiler
optimizations was not to use INDEX or the indexed address modes, but to do an
appropriate autoincrement/-decrement in the last reference of a variable in
the loop, and use relative addressing with a MOVAx when skipping to the next
row (for multidimensional arrays). RISC was at work even then, you know.
Jan
| |
|
| In article <470d4416$1@news.meer.net>, Greg Lindahl <lindahl@pbm.com> wrote:
>In article <fejens$1nj$1@reader1.panix.com>, Seth <sethb@panix.com> wrote:
>
>
>You're cross-posting to comp.lang.fortran. Fortran has a restricted
>kind of pointer which has some properties considerably different from,
>say, C pointers. And actually there are some debugging C
>implementations which do have a base and bound associated with all
>pointers.
There are algorithms where pointers can point to things in different
arrays, so they can't be limited by base and bound (or, if they are,
they might point places they're not supposed to).
Seth
| |
| Greg Lindahl 2007-10-15, 6:57 pm |
| In article <fer73k$lbb$1@reader1.panix.com>, Seth <sethb@panix.com> wrote:
>In article <470d4416$1@news.meer.net>, Greg Lindahl <lindahl@pbm.com> wrote:
>
>There are algorithms where pointers can point to things in different
>arrays, so they can't be limited by base and bound (or, if they are,
>they might point places they're not supposed to).
The base and bound are picked according to the size of the thing
pointed to when the pointer is assigned. In the example you're talking
about, the pointer into array A will have the base,bound of array A,
while a pointer into array B will have the base,bound of array B. And
if this second pointer is later assigned to point to an element of A,
it gets the base and bound of array A. The base,bound are only checked
when you do pointer arithmetic, such as p++ or p[10].
-- greg
|
|
|
|
|