Register keyword and "as if" rule...

Discussion in 'C Programming' started by Snis Pilbor, Oct 13, 2006.

  1. Snis Pilbor

    Snis Pilbor Guest

    With the "as if" rule in play, doesn't that effectively render the
    "register" keyword completely useless?

    Example: I make a silly compiler which creates code that goes out of
    its way to take a full 10 minutes every time a "register" declared
    variable is read from or written to. Besides this lag, everything else
    runs as expected. Then my compiler is still C compliant, aye?

    If so, then it is unwise for any programmer to ever use the "register"
    keyword if they want their code to run smoothly on all implementations:
    their programs might get compiled by my silly compiler someday, and
    then they'll be really blushing :*)

    Or, more realistically, my compiler could simply ignore the "register"
    keyword outright (except to issue diagnostics if it were used in a
    syntactically bad way or its namespace violated).

    Or does the standard actually make some assumption that the
    implementation has things called "registers"?
     
    Snis Pilbor, Oct 13, 2006
    #1
    1. Advertisements

  2. Snis Pilbor said:
    Yes. It would still be conforming if it went out of its way to take a full
    10 minutes every time you read from or wrote to an object that was *not*
    register-qualified. So the argument is spurious.
    That isn't a reason not to bother with register. The best reason not to
    bother with register is that modern compilers are far better at deciding
    what to put into registers than the vast majority of programmers.
    More likely you will be. :)
    Many compilers behave in precisely this way.
    No, it simply specifies the syntax, and leaves the decision up to the
    implementor.
     
    Richard Heathfield, Oct 13, 2006
    #2
    1. Advertisements

  3. Snis Pilbor

    dcorbit Guest

    For the past ten years, the register keyword has been useless anyway.

    The compiler will choose what should be a register and what should not
    better than you will (if the compiler is any good).

    By naming something as a register, certain operations become impossible
    (e.g. you can't take the address of a register).

    The same thing goes for 'inline' which was obsolete before it was
    formally introduced.

    Optimization hints in general are not nearly so important as they were
    20 years ago.
     
    dcorbit, Oct 14, 2006
    #3
  4. Snis Pilbor

    pete Guest

    The register keyword tells the compiler
    that you think that you know more about optimization
    than the compiler does.

    The only way to use "register" effectively,
    is on a per implementation basis with timed tests.
     
    pete, Oct 14, 2006
    #4
  5. Snis Pilbor

    Thad Smith Guest

    I have read that claim many times. While it may be true, I would rather
    the compiler honor the request when made so that the careful programmer
    has the opportunity to improve his generated code. I don't care that a
    careless programmer can easily make it worse. Unfortunately (in my
    opinion), most modern compilers ignore that hint.

    The one thing that the programmer can know that the compiler doesn't is
    the relative frequency of execution paths, which may be important for
    choosing the proper register allocation.
     
    Thad Smith, Oct 14, 2006
    #5
  6. The carefull programmer of yesterday make it impossible to get correct
    performance from his code in today's implementation if the implementation
    were to honor his request.

    Yours,
     
    Jean-Marc Bourguet, Oct 14, 2006
    #6
  7. Snis Pilbor

    Malcolm Guest

    If you were writing a compiler, how would you use the keyword? Given that
    we've got a spare word that won't break old programs.
     
    Malcolm, Oct 14, 2006
    #7
  8. For starters, the guarantee that the object's address will never be
    taken could introduce some opportunities for optimizations (though for
    local variables the compiler can probably figure that out for itself).

    I might ignore it by default, or perhaps give it some small weight in
    deciding whether to assign a variable to a register, but provide a
    command-line option to assign a higher weight.

    This assumes, of course, that my optimizer really is better at
    register allocation than most programmers; I'd want to test that
    assumption on some real code before making a final decision on what
    the default behavior should be.
     
    Keith Thompson, Oct 14, 2006
    #8
  9. Snis Pilbor

    Eric Sosman Guest

    As a careful programmer, you no doubt made a careful series
    of measurements to figure out which variables merit `register'
    and which do not. You may even have discovered some variables
    for which adding `register' slows down the code -- for example,
    by forcing a save/restore the compiler would not otherwise have
    generated, or by depriving the compiler of scratch registers it
    could have used for other purposes. (I have seen this happen,
    back in the Bad Old Days when `register' was the C programmer's
    "abracadabra.")

    But all your measurements are inextricably tied to just one
    version of one compiler on one machine. As a careful programmer,
    then, you need to repeat your measurements on the other platforms
    of interest, and use #if magic so that you'll get optimal code
    from gcc and Visual C++ and Frobozz Magic C, on Xeon and Opteron
    and PowerPC and DS9000. And you'll need to do the whole job over
    again when you patch or upgrade a compiler, or when a faster model
    of a processor chip changes the relative costs of register- and
    memory-resident data ...

    A question: If the last smidgen of speed is so important to
    you that you're willing to become the slave of the machine instead
    of 'tother way about, why are you messing around with compiled
    languages in the first place? Shouldn't you be writing machine
    code, or at the very least assembly code?

    I am not claiming that micro-optimization in general and
    `register' in particular are always bad ideas, but I do claim
    that they are seldom good ideas. The techniques developed
    thirty years ago have been largely overtaken by the economics
    of progress: CPU cycles used to be costlier than programmer
    cycles, but the balance is now reversed. Corner cases will
    always be with us, but the corners have been shrinking.
    Compilers *can* know this, and with more accuracy than the
    programmer is usually able to provide. The compiler instruments
    the compiled code, you run the program over your universe of test
    cases to generate counts and stuff, and finally you recompile
    using both the source and the "feedback" data. This was cutting-
    edge stuff fifteen years ago, and commercial compilers have been
    using the technique for at least a decade.
     
    Eric Sosman, Oct 14, 2006
    #9

  10. Well, generally yes, but sometimes, NO.

    The glitch in the ointment is that optimizing compilers try to minimize
    the overall run time.

    That's really keen and swell if you care about the time from engine
    start to hitting the pub.

    But there are many real-world situations where certain snippets of
    code HAVE to run as fast as possible, in order to keep screens from
    flickering, while maybe 95% of the code, being background or keypress
    handling code, could be running at interpreted COBOL speeds. A
    flight-control computer is a good example-- the keypresses come in very
    rarely, but managing the rudder position had better happen every
    millisecond.

    But your typical compiler will try to speedup ALL the code, which in a
    register-tight environment, such as the x86, means every register the
    compiler allocates to a keyboard key handling loop, is a register that
    won't be available for the rudder-damping code (assuming there's a
    minimum of slow register save/restores being done).

    So in those cases where pinpoint optimization is really needed, hints
    like "register" might be appropriate.
     
    Ancient_Hacker, Oct 14, 2006
    #10
  11. Snis Pilbor

    Malcolm Guest

    I meant, how wouold you extend the keyword.
    For instnace, we could use "register" to register a pointer for bounds
    checking. It would be perfectly compliant, but extend the language in a
    useful way.
     
    Malcolm, Oct 14, 2006
    #11
  12. Oh, I see.

    I wouldn't re-use "register". If I wanted to implement an extension,
    I'd use some reserved identifier like __foobar__.

    Or, if I were trying to create a new version of the standard, I'd
    provide another meaning for "static". :cool:}
     
    Keith Thompson, Oct 14, 2006
    #12
  13. Snis Pilbor

    Old Wolf Guest

    All register variables are local variables.
     
    Old Wolf, Oct 15, 2006
    #13
  14. Yes.
     
    Keith Thompson, Oct 15, 2006
    #14
  15. Snis Pilbor

    Jack Klein Guest

    [snip]

    Can you point to any actual tests that back up this often made and, in
    my experience, totally incorrect truism?

    In fact, it is relatively easily to concoct sample code that the best
    optimizing compiler in the world cannot do as good a job of deciding
    which local objects to keep in registers, as can a programmer who
    knows the range of the data passed to the function.

    Think loops whose counts depend on the value of parameters.
     
    Jack Klein, Oct 15, 2006
    #15
  16. Snis Pilbor

    Jack Klein Guest

    It still is, in come cases. Perhaps not in writing tiered middleware
    under a desktop GUI, but C has more uses than that.
    Dann straight its tied to just one compiler on one processor. Quite
    often, when writing code to be run during interrupts on systems with
    hard real time requirements, that is all that matters. Once such a
    system ships, the compiler version will not be changed, no matter what
    new version the vendor ships.
    How many times have you written interrupt service routines in C that
    are executed 20,000 times per second?
    There still are, and always will be, cases where CPU cycles are the
    costliest resource of all, although very few of these are appear on
    the typical desktop.
    Sadly, you are quite wrong about the state of many commercial
    compilers, especially those for the embedded market where it is often
    required to extract the maximum performance out of the minimum number
    of clock cycles.
     
    Jack Klein, Oct 15, 2006
    #16
  17. Snis Pilbor

    Jack Klein Guest

    Interesting assertion. Can you point to any measured test data to
    back it up?
    The compiler? Is there only one? What about all the others? Perhaps
    you really mean "most compilers" (doubtful), "some compilers", "the
    compilers I use most", or "my favorite compiler"?
    Anyone who uses the "register" keyword without knowing how the
    particular compiler in use generates code for the underlying processor
    platform in use is a fool, as is any user of premature optimizations.
    Still a fool, but less so, if he/she does not actually measure and
    verify that the optimization, be it the use of the register keyword,
    the inline keyword, or various other tricks, actually improves the
    executable in the desired fashion.
    Again, I have not seen anyone produce a link to any studies that prove
    this. And like anything else about the C language, evidence that
    "most compilers", or even "all compilers except one", do better than
    the programmer can is not a general proof.

    The register keyword, and the inline keyword, now that we have it, are
    tools that can be used effectively by someone who knows (and verifies)
    what they do in a particular situation. And, like virtually all
    optimization techniques, they can be misused much more easily by those
    who do not know what they are doing.
     
    Jack Klein, Oct 15, 2006
    #17
  18. Jack Klein said:
    I'd put the boot on the other foot, and ask the programmer who wishes to use
    'register' to show that it reduces the runtime significantly[1]. If it
    does, fine, let him use it.

    [1] Which leads to the question "when is a runtime reduction 'significant'?"
    But that's another story.
     
    Richard Heathfield, Oct 15, 2006
    #18
  19. Do you have any measured test data to refute it?

    (The question is not meant to imply that you don't have such data.)
     
    Keith Thompson, Oct 15, 2006
    #19
  20. Snis Pilbor

    Thad Smith Guest

    Yes, I do make such tests and measurements when it matters.
    Jack is right on. As an embedded programmer, I have a choice of
    dropping to assembly or tweaking the C code to meet constraints. If I
    switch compilers or processors it changes. It still can be the best
    option for my product.
    That's the sort of scenario I sometimes work with, as well.
    Right again. Also, there are times to minimize the maximum execution
    path or only a particular portion of code, not just the overall average.
    I am not aware of any such automated tools for low-end embedded
    market, where execution speed may be critical.

    A product developer uses a range of techniques, when needed, to achieve
    project goals, including algorithm choice, selecting data precision,
    changing the processor clock, dropping to assembly, changing processor
    model, etc. Having the compiler do something potentially useful with
    the register keyword beats ignoring it. A programmer can always abstain
    from using the feature and let the compiler do its best, which is the
    probably best in most, but not all, cases.
     
    Thad Smith, Oct 15, 2006
    #20
    1. Advertisements

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 (here). After that, you can post your question and our members will help you out.