How do I select register variables in C?

Please note: I was originally going to call this question "When to use registers in C?", However it seems like someone has already beat me with a beat . However , the question of how this question was asked versus the title is a bit misleading and I believe this question is unique and not deceiving it.

While this question should really have been titled "Are register

variables really faster?", I really want to know when to use registers

. It's obvious to me that they are actually faster, but obviously your processor has so many registrations on the chip and therefore you are limited in what you can store on them.

So my question is, how do I choose which variables should be qualified with register

? Variables that are used with a specific frequency? Variables of a specific size or type? Variables used in computational tasks? Something else?

I look at it this way: to every product owner or stakeholder, every bug or feature is "prioritized" and critical. But if you really analyze their needs, you will see that some features are actually "prioritized" than others. With code, you want it to run as fast as possible, and so I'm pretty sure every variable is a candidate for performance optimization / tuning. But I would suggest that if you are really analyzing a program (or a C compiler, if you will gcc

), I'm sure there is a way to determine which variables are best suited to use with register

.

+3


source to share


4 answers


First, let me tell you, don't be fooled by the presence register

in the source code C

.

Your compiler is completely free to ignore it (and most of the time it does). In a modern compiler, use register

is most likely useless.



Typically any "standard" compiler will have its own algorithm for discovering and placing the appropriate variables for allocation to registers (or not). In most cases, they are surprisingly correct. Leave them to them.

FWIW. Remember only one thing: cannot get the address of a variable register

. This is the only reason (if we can count it as a "reason") to use register

. may be.

+6


source


There are times when it register

is useful ... when used with an extended assembly.

#define STACK_POINTER "esp"
char **environ;
_start(void){
  register long *sp __asm__( STACK_POINTER );
  long argc = *sp;
  char **argv = (char **)(sp + 1);
  environ = (char **)(sp + argc + 1);
  exit(main(argc, argv, environ) );
  __builtin_unreachable(); //or for(;;); to shut up compiler about returning
}

      

On Linux (maybe others), elf binaries push _start args on the stack, even if the architecture passes a number of arguments as registers. Since there is no standard way to access the stack pointer, you either need to start writing in the entire assembly or use extensions like this to access a specific named register via a variable. You can also assign a value



register long *syscall_num __asm__( "eax" ) = __NR_open;
...

      

This is useful for the opposite situation, where functions usually pass arguments on the stack, but a special function (syscall, etc.) requires parameters to be passed in certain registers.

Theses of the two mechanisms will use registers if the compiler supports that syntax, but not, using register int i;

or the like has no guarantees.

0


source


The keyword register

is useful when defining extensions for ABI calls, such as creating functions that can pass multiple parameters; or globally allocate the register for the local memory manager, etc.

register int g_imag __asm__ ("r14");

int complex_multiply(int real, int imag, int r2, int i2)
{
    g_imag = real*i2 + imag*r2;    // put to "global" variable
    return real*r2 - imag*i2;
}

      

Use only user-retained registers to ensure that functions that are used r14

for other purposes spill their contents onto the stack first. The downside is the reduction in the available registers in other functions, as others have noted that this only works when it works.

0


source


As you know, register is the RAM used by the processor. They are mostly limited by their memory space, some are 8 bits and some are 256 bits. I remember this about 10x faster than DRAM, for example 5 to 50 ns (not sure).

The use of this parameter depends on which field you are working in. For example, when working with embedded electronics it is useful to use register, when you use a global constant a lot, setting it as a register will make your program "faster".

But keep in mind that this is a matter of optimization, unless you are working with heavy demanding algorithms or embedded electronics, there is no need to dive into it. As stated above, compilers can detect frequently used variables and try to store them in the register automatically.

But if you really want to use it, keep in mind that you must set variables or constants that are very frequently used and do not exceed register size!

-1


source







All Articles