Thread: Speed of pointers vs. speed of arrays/structs

  1. #16
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Kempelen View Post
    I don't know why, but mingw get an error "syntax error before asm", any idea?
    With the code I just posed, or with your post?

    My code compiles with gcc-mignw 3.4.2.

    What options are you using for gcc? If you give -ansi, then all asm-statements are syntax errors, since asm is not ansi compliant. You can still use inline assembler if you use __asm__ instead of asm, in which case my code also compiles with -ansi.

    Code:
    register int x __asm__("ebx");
    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  2. #17
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Kempelen View Post
    In speed issues, I have learn the hard way with a few years of experience that the best is to test it. Althought maybe I will not get anything.
    Yes. But in my experience (and I spent literally a couple of years at AMD with most of my time looking at performance), letting the compiler assign registers works better than trying to tell the compiler what to do. In very specific instances, global registers MAY be better - but that would be rare and unusual, rather than the common case.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #18
    Registered User
    Join Date
    Feb 2008
    Posts
    147
    Quote Originally Posted by matsp View Post
    With the code I just posed, or with your post?

    My code compiles with gcc-mignw 3.4.2.

    What options are you using for gcc? If you give -ansi, then all asm-statements are syntax errors, since asm is not ansi compliant. You can still use inline assembler if you use __asm__ instead of asm, in which case my code also compiles with -ansi.

    Code:
    register int x __asm__("ebx");
    --
    Mats
    Hi Mats, thx for you support. At the end, I think i can't test it, because I have multiple files, and if I declare a variable as register, then it is not extern and vice-versa. Only one storage class type is allowed.
    I have test it declaring the variable as register in .h, and normal one in .c. It compile good but dont get expected result when run.
    Anyway I didn't confident I would obtein speed improvements.

  4. #19
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Can't you use the global register declaration in a header-file (that is then included everywhere)[1]? I'm pretty sure that will work. Although I still think the compiler on it's own will do a better job, so you may well be right that you won't benefit much (if anything). I'd be interested to see what happens, however.

    [1] This really shouldn't cause any problems, as there won't be a global symbol for something that the compiler makes into a register.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  5. #20
    Registered User
    Join Date
    Feb 2008
    Posts
    147
    Quote Originally Posted by matsp View Post
    Can't you use the global register declaration in a header-file (that is then included everywhere)[1]? I'm pretty sure that will work. Although I still think the compiler on it's own will do a better job, so you may well be right that you won't benefit much (if anything). I'd be interested to see what happens, however.

    [1] This really shouldn't cause any problems, as there won't be a global symbol for something that the compiler makes into a register.

    --
    Mats
    I can use it. I was refering that the version of the program that is declared as extern is running OK and I get the expected results from the program. If I declare as register in the way writed above, I can compile, but when run the program don't show the same result as the non-register version, even a crash. dont know why.
    Also, when compile I get an error : "warning: unknow register name: reg" that I dont understand (dont know where 'reg' came from)

    (EDIT: forget to say that the crash is in a line where the global reg var is not used, so it is more extrange.....isn't it?)
    Last edited by Kempelen; 06-26-2008 at 06:53 AM.

  6. #21
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Kempelen View Post
    I can use it. I was refering that the version of the program that is declared as extern is running OK and I get the expected results from the program. If I declare as register in the way writed above, I can compile, but when run the program don't show the same result as the non-register version, even a crash. dont know why.
    Also, when compile I get an error : "warning: unknow register name: reg" that I dont understand (dont know where 'reg' came from)
    I'll have a little play...

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  7. #22
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    This works:
    Code:
    // asmvars.h
    register int x __asm__("ebx");
    
    //asmvars.c
    #include <stdio.h>
    
    #include "asmvars.h"
    
    extern int getx(void);
    
    int main()
    {
      x = 7;
      printf("x = %d\n", getx());
      return 0;
    }
    
    // asm2.c
    #include "asmvars.h"
    
    int getx()
    {
      return x;
    }
    compiled with
    Code:
    gcc -Wall -ansi asmvars.c asm2.c
    And I looked at the code generated, it is using ebx when I expect it to.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  8. #23
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    I just had a couple of thoughts:
    First of all, the register you choose must be one that is "preserved" by the compiler - otherwise, it won't work. EBX, EDI, ESI are your only choice (but 64-bit machine also has R8-R15 for you to use), as EAX, ECX, EDX, EBP and ESP are used by the compiler either as scratch-pad registers (presumed lost when calling functions) or as very specific use (ESP -> stack pointer, EBP -> frame pointer).

    Second, I doubt this is a commonly used feature in gcc - there may well have bugs in the compiler that make things "go wrong" if you use it in a sufficiently complex piece of code - it may for example "forget" that the register is a global variable, and use it for temporary use.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  9. #24
    Registered User
    Join Date
    Feb 2008
    Posts
    147
    Quote Originally Posted by matsp View Post
    I just had a couple of thoughts:
    First of all, the register you choose must be one that is "preserved" by the compiler - otherwise, it won't work. EBX, EDI, ESI are your only choice (but 64-bit machine also has R8-R15 for you to use), as EAX, ECX, EDX, EBP and ESP are used by the compiler either as scratch-pad registers (presumed lost when calling functions) or as very specific use (ESP -> stack pointer, EBP -> frame pointer).

    Second, I doubt this is a commonly used feature in gcc - there may well have bugs in the compiler that make things "go wrong" if you use it in a sufficiently complex piece of code - it may for example "forget" that the register is a global variable, and use it for temporary use.

    --
    Mats
    Hi Mats.
    I have tried some of them:
    - ebx register. It compiles OK, but when run the program crashs in a line where de var is not used. I suppose the compiler can't do the work correctly.
    - edi register. I get an error when compile: "unable to find a register to spill in class 'DIREG'". I think compiler can't do the compilation with that register.
    - esi register: It compiles OK, but when running it crashs in a line where using the var.

    As I understand, I think I can not use this trick. I was intriged by the test and result, but I was not confident to obtein good result. My program has around 16000 lines of code, and I think it very difficult to the compiler to try this, even more...... it is an unusual thing so I am forgeting this.

    Anyway, I like the idea of having a pointer to a global struct where all global var are stored. Storing in a register is only a minor detail. Not only for efficience (My test look as is the same), but for specific design of my program. And of course I tried to avoid global variables where I can....

    only one more think, I would like to know how exactly a global var work at runtime and why they are not advisabled. Is for speed or for other considerations?. I was thinking in not having them, but have a pointer that is passed between functions, (or a global pointer), with a typedef in a header, so no extern variables, only a pointer that point to "my global memory storage". sound good? do you see any adventage in this?

    thanks again. I am learning a lot with this kind of things.

  10. #25
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    They are bad because the compiler has problems optimizing them and because they are global - their state can change anytime, anywhere. It's a great way to open your program to bugs, in other words.
    That is why they are not recommended.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  11. #26
    Malum in se abachler's Avatar
    Join Date
    Apr 2007
    Posts
    3,195
    Quote Originally Posted by Kempelen View Post
    What's faster, pointers manipulation or subscripting with arrays/structs?

    Also, I have read that if having lots of global vars, it is better to join them in a typedef struct and create a global register var pointer to them. Something like this:

    Code:
    typedef struct {
    int a
    int b
    char s[10];
    ...
    } t_data;
     
    register t_data *p
    Access global data as p->a, p->b, etc..... This look liike faster but why? is this trick speed improvement.
    Thx.
    FS
    there will be no difference. Used to be that global variables where faster because their addresses were hard coded intot he executable, and then fixed up at runtime. This is usually not the case anymore.

  12. #27
    Registered User
    Join Date
    Feb 2008
    Posts
    147
    Hi,

    Yesterday I was curious and I was reading here and there. I google and read about the keyword 'restrict' and see that it could be used to let the compiler know if a variable changes or not and so evoid aliasing problems. For my surprise I read in my C books about it, but found no reference to this keyword. What's the purpose of this keyword and how can it bi used? is possible to use it with global vars and let the computer optimizing?

    An talking of another issue, I was talking with a work colleage about if it is better using pointers or arrays. He told me it is better tu use arrays because pointers can cause speed penalization when using in a loop. He gave me the following example:

    Code:
       for (int x=0; x<1000; x++)
           *p++ = ...
    He pointed that sametimes, the pointer can point to itself and so assigning to p can change its value. For that reason the compiler need to reload the value of the pointer per iteration.
    Also he said that compiler can't know if the pointer changes its value outside the loop, so it generates code to update the pointer with its incremented value. This problem dont appear with arrays access.

    thx.

  13. #28
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Kempelen View Post
    Hi,

    Yesterday I was curious and I was reading here and there. I google and read about the keyword 'restrict' and see that it could be used to let the compiler know if a variable changes or not and so evoid aliasing problems. For my surprise I read in my C books about it, but found no reference to this keyword. What's the purpose of this keyword and how can it bi used? is possible to use it with global vars and let the computer optimizing?
    It may be possible - restrict is a C99 keyword, which probably explains why most books (mostly written to comply with C89, or somtimes doesn't comply with any standard, but uses a specific compiler "as the standard"). Since most people capable of writing C programming books are spending there time and effort on writing more profitable C++ books, C99 standard compliant books aren't easy to find).

    An talking of another issue, I was talking with a work colleage about if it is better using pointers or arrays. He told me it is better tu use arrays because pointers can cause speed penalization when using in a loop. He gave me the following example:

    Code:
       for (int x=0; x<1000; x++)
           *p++ = ...
    He pointed that sametimes, the pointer can point to itself and so assigning to p can change its value. For that reason the compiler need to reload the value of the pointer per iteration.
    Also he said that compiler can't know if the pointer changes its value outside the loop, so it generates code to update the pointer with its incremented value. This problem dont appear with arrays access.

    thx.
    Possibly true, but in my experience, modern compilers do pretty well on converting arrays to pointers and pointers to arrays.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  14. #29
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    He pointed that sametimes, the pointer can point to itself and so assigning to p can change its value. For that reason the compiler need to reload the value of the pointer per iteration.
    Could you elaborate? A pointer is of a different type from a pointer to itself, so how can it point to itself unless there is an error in the code?

    I suspect that the example is a strawman to begin with since it seems to deal with a loop index while iterating with a pointer, whereas there is the idiom of using the pointer to iterate directly.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  15. #30
    Registered User
    Join Date
    Feb 2008
    Posts
    147
    Quote Originally Posted by matsp View Post
    It may be possible - restrict is a C99 keyword, which probably explains why most books (mostly written to comply with C89, or somtimes doesn't comply with any standard, but uses a specific compiler "as the standard"). Since most people capable of writing C programming books are spending there time and effort on writing more profitable C++ books, C99 standard compliant books aren't easy to find).
    Mats
    Hi Mats,
    do you know exactly how to use the restrict keyword? I am trying to put in the .c file where I declare my vars, but it said "invalid use of restrict". Also google but didn't find anything....

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. sorting number
    By Leslie in forum C Programming
    Replies: 8
    Last Post: 05-20-2009, 04:23 AM
  2. moving pointers to pointers
    By Benzakhar in forum C++ Programming
    Replies: 9
    Last Post: 12-27-2003, 08:30 AM
  3. pointers to pointers within structs
    By Lord_azrael99 in forum C Programming
    Replies: 2
    Last Post: 08-28-2003, 04:29 AM
  4. Pointers pointers pointers....
    By G'n'R in forum C Programming
    Replies: 11
    Last Post: 11-02-2001, 02:02 AM
  5. Pointers pointers pointers...
    By SMurf in forum C Programming
    Replies: 8
    Last Post: 10-23-2001, 04:55 PM