Using temporary register Variable

S

Shankar Agarwal

I was trying to use a variable whose value is temporary and i don't want
it to go to the memory for performance reasons. Is there a way to specify
the variable like that so that any assignment to the variable does not go
to memory. I tried the type register but it does not seem to work.
Thanks
Shankar
 
M

Mark A. Odell

I was trying to use a variable whose value is temporary and i don't want
it to go to the memory for performance reasons. Is there a way to
specify the variable like that so that any assignment to the variable
does not go to memory. I tried the type register but it does not seem to
work.

'register' is just a hint, easily ignored by the compiler. Alas, this is
your only standard method to get into a real register. Assembler is your
friend if things are this critical.
 
T

Tristan Miller

Greetings.

I was trying to use a variable whose value is temporary and i don't
want it to go to the memory for performance reasons. Is there a way to
specify the variable like that so that any assignment to the variable
does not go to memory.

No, not in standard C. As you've discovered, the "register" specifier
is no more than a hint to the compiler, which it's free to ignore.
(And as most modern compilers are far better at optimizing code than
the average human, they usually do ignore it.) Your compiler may
provide an extension to force register allocation. Is the code really
that performance-critical, though? Optimization should always be done
at the algorithmic level first; worrying about little things like
register variables is rarely worth one's effort.

Regards,
Tristan
 
M

Malcolm

Shankar Agarwal said:
I tried the type register but it does not seem to work.
"register" is only a hint. You can try changing compilers, you can try
changing the type of the variable (is it an int?), you can try simplifying
the function it is in and removing other variables, though of course this
might not be possible.
Virtually every C compiler comes with an inline assembler, and you probably
want to resort to this.
 
J

Joe Wright

Malcolm said:
"register" is only a hint. You can try changing compilers, you can try
changing the type of the variable (is it an int?), you can try simplifying
the function it is in and removing other variables, though of course this
might not be possible.
Virtually every C compiler comes with an inline assembler, and you probably
want to resort to this.

Ah.. but then it wouldn't be C, would it? Portable, etc.
 
M

Malcolm

Joe Wright said:
Ah.. but then it wouldn't be C, would it? Portable, etc.
What he can do is write two versions of the function, one in C and one using
the assembler. Then use #ifdef [something defined by the compiler which
tells you what it is] to conditionally compile the code.

This isn't a perfect solution, since there's always the risk that a
maintainer might alter one version of the function and not another, breaking
the program. However it's probably the best that can be done.
 
A

August Derleth

Ah.. but then it wouldn't be C, would it? Portable, etc.

It's not off-topic to say that you might need to use a non-portable method
to accomplish something, but the person should have the sense not to come
back here to discuss the nonportable aspects of the code (except maybe to
verify that they are, in fact, nonportable).
 
D

Dan Pop

In said:
I was trying to use a variable whose value is temporary and i don't want
it to go to the memory for performance reasons. Is there a way to specify
the variable like that so that any assignment to the variable does not go
to memory. I tried the type register but it does not seem to work.

If your compiler decided to ignore your request for keeping the variable
in a register, it is usually because it has better uses for the available
registers and satisfying your request would result in slower code. Do you
have a good reason for wanting to slow down the generatede code?

Dan
 
M

Malcolm

Dan Pop said:
If your compiler decided to ignore your request for keeping the
variable in a register, it is usually because it has better uses for the
available registers and satisfying your request would result in slower
code. Do you have a good reason for wanting to slow down the
generatede code?
It's not always as easy as that.

Consider this function.

void child_benefit(STUDENT *st, int N)
{
int i;
for(i=0;i<N;i++)
{
for(j=0;j<st.nkids;j++)
{
st.benefit += 100;
}
}
}

Now as 21st century Westerners we know that N is likely to be large (lots of
students at a univerity) and that 99% of the time the nkids member will be
zero (most students have no children).
Therefore if there is a choice between keeping i in a register and keeping a
register hardwired to 100, we should keep i in the register.
Change the function to "professors" instead of "students" and "number of
lectures" instead of "number of children" and the dynamics chage again -
most universities only have a handful of professors who give quite a lot of
lectures in a year.
The compiler has no way of knowing this, and sometimes the human programmer
does know best.
 
C

Chris Dollin

Malcolm said:
It's not always as easy as that.

Consider this function.

void child_benefit(STUDENT *st, int N)
{
int i;
for(i=0;i<N;i++)
{
for(j=0;j<st.nkids;j++)
{
st.benefit += 100;
}
}
}

Now as 21st century Westerners we know that N is likely to be large (lots
of students at a univerity) and that 99% of the time the nkids member will
be zero (most students have no children).
Therefore if there is a choice between keeping i in a register and keeping
a register hardwired to 100, we should keep i in the register.


Just in passing, it seems to me that in this function we can keep all
of N, st, i, and 100 [if we need to] in registers. So it's not a
discriminator.

[Yeah, yeah, I'm stuck on this x86 box, but my heart [1] belongs to the
ARM.]

[1] That part of it that doesn't belong to Renaissance, Reiner Knizia,
Patricia McKillip, and Karnataka.
 
D

Dan Pop

Dan Pop said:
If your compiler decided to ignore your request for keeping the
variable in a register, it is usually because it has better uses for the
available registers and satisfying your request would result in slower
code. Do you have a good reason for wanting to slow down the
generatede code?
It's not always as easy as that.

Consider this function.

void child_benefit(STUDENT *st, int N)
{
int i;
for(i=0;i<N;i++)
{
for(j=0;j<st.nkids;j++)
{
st.benefit += 100;
}
}
}

Now as 21st century Westerners we know that N is likely to be large (lots of
students at a univerity) and that 99% of the time the nkids member will be
zero (most students have no children).
Therefore if there is a choice between keeping i in a register and keeping a
register hardwired to 100, we should keep i in the register.


Processors are that register starved that they have to make this choice
typically do not need to keep 100 in a register: it can be used as an
immediate operand of the instruction(s) needing it.

Dan
 
M

Malcolm

Dan Pop said:
Processors are that register starved that they have to make this choice
typically do not need to keep 100 in a register: it can be used as an
immediate operand of the instruction(s) needing it.
It's only an example.
ADD register1, register2
might well be faster than
ADD register1, 100

We can always modify the function by adding extra operations to soak up more
registers, without altering the point being made.
 
D

Dan Pop

It's only an example.
ADD register1, register2
might well be faster than
ADD register1, 100

It may be faster, but not by a significant amount. Loading the constant
from memory to a register and then using a register-register add would be
significantly slower and will cause a register to be spilled, making it
even slower.
We can always modify the function by adding extra operations to soak up more
registers, without altering the point being made.

The idea is that the compiler can make *local* decisions about which
variables are best kept in registers at any given point, but if it
has to honour a programmer request, the same variable will have to
be kept in a register for the whole duration of the function, thus
blocking a register even when the variable in question is not used
often enough to justify its presence in a register.

Dan
 
M

Malcolm

Dan Pop said:
It may be faster, but not by a significant amount. Loading the constant
from memory to a register and then using a register-register add would >
be significantly slower and will cause a register to be spilled, making it
even slower.
But if we load a register with 100 at the start of the function, and don't
modify it, we incur the overhead of the memory access only once. We then
save maybe many thousands of cycles because
ADD register1, register2
is a cycle faster than
ADD register1, 100.
The idea is that the compiler can make *local* decisions about which
variables are best kept in registers at any given point, but if it
has to honour a programmer request, the same variable will have to
be kept in a register for the whole duration of the function, thus
blocking a register even when the variable in question is not used
often enough to justify its presence in a register.
No you haven't understood the point I was making. We know that universities
typically have tens of thousands of students, but that only a few of those
students have children. We can use this information to make optimising
decisons which it is impossible for a compiler to make.
 
D

Dan Pop

be significantly slower and will cause a register to be spilled, making it
But if we load a register with 100 at the start of the function, and don't
modify it, we incur the overhead of the memory access only once. We then
save maybe many thousands of cycles because
ADD register1, register2
is a cycle faster than
ADD register1, 100.
No you haven't understood the point I was making. We know that universities
typically have tens of thousands of students, but that only a few of those
students have children. We can use this information to make optimising
decisons which it is impossible for a compiler to make.

And you haven't understood the point I was making. Even if we know this
and the compiler doesn't, its decision may still be better than ours,
because ours means that one register is blocked for the whole duration
of the variable, while the compiler can decide to keep that variable
in a register only when that variable is "hot". I.e. the compiler can
take our request as a hint that that variable is a good candidate for
register allocation when it is "hot", but ignore the request during the
execution of other parts of the function.

Dan
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top