Performance difference when accessing using pointer and double pointer
Asked Answered
O

4

6
  1. Is there any performance difference when we access a memory location by using a pointer and double pointer?
  2. If so, which one is faster ?
Oahu answered 13/2, 2014 at 11:28 Comment(2)
It depends on the machine I guess, but AFAIK - 'single pointer' is at least as fast as 'double pointer' (for every architecture I am aware about, but I am really not a low level expert)Ferrosilicon
A "double pointer" is not a thing in C. What you're playing with here is probably (since you don't show any actual code) a "pointer to pointer".Breuer
F
7

There is no simple answer it, as the answer might depend in the actual machine. If I remember correctly some legacy machines (such as PDP11) offered a 'double pointer' access in a single instruction.

However, this is not the situation today. accessing memory is not as simple as it looks and requires a lot of work, due to virtual memory. For this reason - my guess is that double reference should in fact be slower on most modern machines - more work has to be done to translate two addresses from virtual addresses to physical addresses and retrieving them - but that's just educated guess.
Note however, that the compiler might optimize 'redundant' accesses for you already.

For my best knowledge however, there is no machine that has faster 'double access' than 'single access', so we can say that single access is not worse than double access.

As a side note, I believe in real life programs, the difference is neglectable (comparing to anything else done in the program), and unless done in a very performance sensitive loop - just do whatever is more readable. Also, the compiler might optimize it for you already if it can.

Ferrosilicon answered 13/2, 2014 at 11:40 Comment(2)
A good point about the PDP11 and more importantly that it is architecture and not C dependent +1. PDP11 is a little outdated. Are you aware of any more modern architectures that do this?Emanate
@Emanate I am not architecture expert, and I am not familiar with any modern machine that has this semantics, maybe on some embedded systems w/o virtual-memory.. Note however that PDP11 is old but is still in use on some irrigation systems to my best knowledge.Ferrosilicon
E
5

Assuming you are talking about something like

int a = 10;
int *aptr = &a;
int **aptrptr = &aptr;

Then the cost of

*aptr = 20;

Is one dereference. The address pointed to by aptr must first be retrieved and then the address can be stored to.

The cost of

**aptrptr = 30;

Is two dereferences. The address pointed to by aptrptr must first be retrieved. Then the addess stored in that address must be retrieved. Then this address can be stored to.

Is this what you were asking?

Therefore, to conclude using a single pointer is faster if that suits your needs.

Note, that if you access a pointer or double pointer in a loop, for example,

while(some condition)
    *aptr = something;

or

while(some condition)
    **aptrptr = something;

The compiler will likely optimize so that the dereferencing is only done once at the start of the loop, so the cost is only 1 extra address fetch rather than N, where N is the numnber of times the loop executes.

EDIT: (1) As Amit correctly points out the "how" of pointer access is not explicitly a C thing... it does depend on the underlying architecture. If your machine supports a double dereference as a single instruction then there might not be a big difference. He is using the index deferred addressing mode of the PDP11 as an example. You might find out that such an instruction still chews up more cycles... consult the hardware documentation and look at the optimization that your C compiler is able to apply for your specific architecture.

The PDP11 architecture is circa the 1970s. As far as I know (if someone knows are modern architecture that can do this pleas post!), most RISC architectures and don't have such a double dereference and will probably need to do two fetches as far as I am aware.

Therefore, to conclude using a single pointer is probably faster generally, but with the caveat that specific architectures may handle this better than others and compiler optimizations, as I discussed, could make the difference negligible... to be sure you just have to profile your code and read up about your architecture :)

Emanate answered 13/2, 2014 at 11:36 Comment(2)
The address pointed to by aptrptr must first be retrieved - that really depends more on the underlying architecture, and definetly not a C standard (uness you can provide reference?)Ferrosilicon
Yes true C standard doesn't say "how" this should happen. I don't know of many architectures that support a double dereference instruction however, apart from the architecture you've suggested. So, technically I agree the "how" is not a c standard issue but I think most architectures would probably have to do two fetches. I will update the answer to clarify this point.Emanate
D
1

Let's see it in this way:

int var = 5;
int *ptr_to_var = &var;
int **ptr_to_ptr = &ptr;
  • When the variable var is accessed then you need to

    • 1.get the address of the variable
    • 2.fetch its value from that address.
  • In case of pointer ptr_to_var you need to

    • 1.get the address of the pointer variable
    • 2.fetch its value from that address (i.e, address of the variable var)
    • 3.fetch the value at the address pointed to.
  • In third case, pointer to pointer to int variable ptr_to_ptr, you need to

    • 1.get the address of the pointer to pointer variable
    • 2.fetch its value from that address (i.e, address of the pointer to variable ptr_var)
    • 3.again fetch its value from the address fetched in the second step(i.e, address of the variable var)
    • 4.fetch the value at the address pointed to.

So we can say that accessing via pointer to pointer variable is slower than that of pointer variable which in turn slower than that of normal variable accessing.

Decode answered 13/2, 2014 at 12:0 Comment(1)
Like I already stated as a comment to the first answer, it really depends on the machine, unless you can provide a reference that states that it is always the case in C. For example, PDP11: @0(Rx) - Rx is the address of address to the value. (Rx) - Rx is the address of the value. Rx - Rx is the value. All are single instructions.Ferrosilicon
A
1

I got curious and set up the following scenario:

int v = 0;
int *pv = &v;
int **ppv = &pv;

I tried dereferencing the pointers and took a look at the disassembly, which showed the following:

int x;
x = *pv;
    00B33C5B  mov         eax,dword ptr [pv]  
    00B33C5E  mov         ecx,dword ptr [eax]  
    00B33C60  mov         dword ptr [x],ecx
x = **ppv;
    00B33C63  mov         eax,dword ptr [ppv]  
    00B33C66  mov         ecx,dword ptr [eax]  
    00B33C68  mov         edx,dword ptr [ecx]  
    00B33C6A  mov         dword ptr [x],edx

You can see that there is an additional mov instruction for dereferencing there so my best guess is: double dereferencing is inevitably slower.

Athena answered 13/2, 2014 at 12:10 Comment(6)
Did you enable any compiler optimization level?Clop
@Clop No optimization was used.Athena
so my best guess is: double dereferencing is inevitably slower - for the tested architecture(x86 I assume) w/o compiler optimizations.Ferrosilicon
It looks unoptimized, this isn't a very interesting mode to compare. Also - additional x86 instructions are necessarily slower, some CPUs can also optimize register movsClop
@Clop After activating all optimizations the compiler got rid of everything. I've been trying for the past hour to force it to produce at least some ASM, but to no success.Athena
Are you using the generated values somehow? if not then the compiler would simply remove themClop

© 2022 - 2024 — McMap. All rights reserved.