Defeating Optimisation for memcmp()

J

James Kuyper

Martin wrote:
....
I stated at the start of this thread why I wanted to avoid optimising
out the memcmp and have restated it since. Please accept that I need
to do so.

Let me say this frankly: what you say you want to do is pointless, for
precisely the same reason that you can't prevent the optimization. If
there's really a point to what you want to do, you haven't made that
clear. You need to expand your description of the problem to make that
point clear; as soon as you do so, we can tell you what to do to prevent
the optimization.
pcmos is not subject to random change between the calls. We are making
it volatile so that we can *pretend* it is subject to random change in
order to prevent the memcmp from being optimised out (although based
on other contributors' posts to this thread that turns out to perhaps
not be a good idea).

If you can know for certain that you're checking the same block of
memory that was copied over, before it has had any chance to be changed,
then so can a sufficiently intelligent compiler. If the compiler
recognizes that fact, then it can optimize the memcpy() call away, under
the as-if rule. The only options you have are compiler-specific. You
have to use a compiler that isn't smart enough to recognize this fact,
or you can use a smarter compiler in a mode where such optimizations are
turned off.
 
W

Willem

James wrote:
) Let me say this frankly: what you say you want to do is pointless, for
) precisely the same reason that you can't prevent the optimization. If
) there's really a point to what you want to do, you haven't made that
) clear. You need to expand your description of the problem to make that
) point clear; as soon as you do so, we can tell you what to do to prevent
) the optimization.

IIRC, What he wants to do is write to a specific bit of memory, and then
check if the write was OK by reading back the data and comparing.


SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
 
J

James Kuyper

Willem said:
James wrote:
) Let me say this frankly: what you say you want to do is pointless, for
) precisely the same reason that you can't prevent the optimization. If
) there's really a point to what you want to do, you haven't made that
) clear. You need to expand your description of the problem to make that
) point clear; as soon as you do so, we can tell you what to do to prevent
) the optimization.

IIRC, What he wants to do is write to a specific bit of memory, and then
check if the write was OK by reading back the data and comparing.

Since a correct implementation of C guarantees that the comparison
results in an exact match, it can be optimized away. That's also why the
comparison is pointless. As I explained before, the best you can do, if
you suspect a compiler of implementing either memcpy() or memcmp()
incorrectly, is to select a compiler mode that turns off such optimizations.

If that isn't an option, the next-best choice is to perform the copy and
the comparison in two different translation units, which makes it much
harder (but not impossible) to perform such optimizations. The
optimization would have to be done by a smart linker, rather than in the
compiler itself. Linkers with that much intelligence are supposedly
state of the art for C++. With modern implementations of C often
piggy-backed on C++ implementations, I wouldn't rule out the possibility
of optimizations that can only be performed during the linking process.
 
M

Martin

James Kuyper said:
Let me say this frankly: what you say you want to do is pointless, for
precisely the same reason that you can't prevent the optimization. If
there's really a point to what you want to do, you haven't made that
clear. You need to expand your description of the problem to make that
point clear; as soon as you do so, we can tell you what to do to prevent
the optimization.

What I want to do is far from pointless. When I wrote "I want to write code
that will verify that a write to CMOS has succeeded, and ensure that the
compiler does not optimise away the verification" that's exactly what I
wanted to do.

The detail is simply that the code is writing to CMOS (hence the variable
names derived from it). CMOS is an area that has a limited number of writes
available to it (I assumed this was fairly common knowledge). After a
certain amount of use, writes can, do, and have been failing. The code has
not been detecting that and now we've decided it must. We need to tell the
compiler that it mustn't assume that a write to CMOS has succeeded (using
memcpy or whatever) - it *must* perform the verification, using memcmp, or
whatever. It's basically a memory test.

The only reason I can think of for your comments is that you were assuming I
wanted to check the write because I wasn't confident that memcpy was
implemented correctly. As I have now explained, it's because the CMOS may be
failing.

Thanks for your time.
 
J

James Kuyper

Martin said:
What I want to do is far from pointless. When I wrote "I want to write code
that will verify that a write to CMOS has succeeded, and ensure that the
compiler does not optimise away the verification" that's exactly what I
wanted to do.

The detail is simply that the code is writing to CMOS (hence the variable
names derived from it). CMOS is an area that has a limited number of writes
available to it (I assumed this was fairly common knowledge). After a
certain amount of use, writes can, do, and have been failing. The code has
not been detecting that and now we've decided it must. We need to tell the
compiler that it mustn't assume that a write to CMOS has succeeded (using
memcpy or whatever) - it *must* perform the verification, using memcmp, or
whatever. It's basically a memory test.

The only reason I can think of for your comments is that you were assuming I
wanted to check the write because I wasn't confident that memcpy was
implemented correctly. As I have now explained, it's because the CMOS may be
failing.

You said that the memory being pointed at was not volatile. My comments
were predicated on taking you at your word. Now you've described that
memory in a fashion that has to be described as volatile.

The best solution you can use in that case has already been mentioned:
instead of using memcmp(), write your own version that takes pointers to
volatile as arguments. It's pretty trivial to do. The reason the
standard memcmp() is not written that way is that in general its output
would be pretty meaningless: since the pointed-at memory is volatile,
the only thing the return value from volatile_memcmp() would tell you is
how the bytes compared at the times that they were compared. Inherently,
different bytes are necessarily compared at different times, so it
cannot even be considered a snapshot comparison.

However, if you assume that the memory you're looking at is changing
sufficiently slowly, volatile_memcmp() could be a useful and meaningful
thing to define.
 
S

santosh

What I want to do is far from pointless. When I wrote "I want to write
code that will verify that a write to CMOS has succeeded, and ensure
that the compiler does not optimise away the verification" that's
exactly what I wanted to do.

Instead of this ongoing headbanging, why don't you just use a small
assembler routine for this purpose and be done with it? Then no
compiler can get it's grubby hands on your code.

Writing to CMOS is non-portable anyway, so a machine specific routine
should not be too much of a bother.
The detail is simply that the code is writing to CMOS (hence the
variable names derived from it). CMOS is an area that has a limited
number of writes available to it (I assumed this was fairly common
knowledge). After a certain amount of use, writes can, do, and have
been failing. The code has not been detecting that and now we've
decided it must. We need to tell the compiler that it mustn't assume
that a write to CMOS has succeeded (using memcpy or whatever) - it
*must* perform the verification, using memcmp, or whatever. It's
basically a memory test.

The best tool for this sort of job, which requires fine control and the
complete absence of any possible optimisation, is assembler.

<snip>
 
C

Charlie Gordon

Martin said:
What I want to do is far from pointless. When I wrote "I want to write
code that will verify that a write to CMOS has succeeded, and ensure that
the compiler does not optimise away the verification" that's exactly what
I wanted to do.

The detail is simply that the code is writing to CMOS (hence the variable
names derived from it). CMOS is an area that has a limited number of
writes available to it (I assumed this was fairly common knowledge). After
a certain amount of use, writes can, do, and have been failing. The code
has not been detecting that and now we've decided it must. We need to tell
the compiler that it mustn't assume that a write to CMOS has succeeded
(using memcpy or whatever) - it *must* perform the verification, using
memcmp, or whatever. It's basically a memory test.

The only reason I can think of for your comments is that you were assuming
I wanted to check the write because I wasn't confident that memcpy was
implemented correctly. As I have now explained, it's because the CMOS may
be failing.

The volatile keyword is what you need. Qualifying this "unreliable" as
volatile will require that all accesses be coded and not optimized away. Why
don't you write a small loop where you read back each byte that you copy,
and try again a few times upon failure before giving up with an error code.
 

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

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,276
Latest member
Sawatmakal

Latest Threads

Top