force jump table with switch statement (visual c)

P

paul c

Apologies if I'm sending this to the wrong group. If so I'd be grateful
if somebody could point me to the right one.


I'm using microsoft visual c++ 6.0 compiler. My code is C, I just use
the c++ compiler for easier positioning of declarations here and there.


I am putting together a small interpreter that will do a great deal of
iteration and I'd like to avoid using function pointers to my opcode
code because I don't need any machine-level stack pushing, popping,
calling and returning and these seem quite expensive compared to simple
goto's.


Can anybody advise what compile options I might use to force a jump
table when a switch statement is compiled? If I have to use a different
compiler, I will. Also, is there a disassembler or somesuch that will
let me confirm that a jump table was produced?


thanks,
pc
 
S

Skarmander

paul said:
Apologies if I'm sending this to the wrong group. If so I'd be grateful
if somebody could point me to the right one.

I'm using microsoft visual c++ 6.0 compiler. My code is C, I just use the
c++ compiler for easier positioning of declarations here and there.

Try microsoft.public.vc or one of its subgroups.
I am putting together a small interpreter that will do a great deal of
iteration and I'd like to avoid using function pointers to my opcode
code because I don't need any machine-level stack pushing, popping,
calling and returning and these seem quite expensive compared to simple
goto's.


Can anybody advise what compile options I might use to force a jump
table when a switch statement is compiled? If I have to use a different
compiler, I will. Also, is there a disassembler or somesuch that will
let me confirm that a jump table was produced?
You definitely want a compiler-specific ng. Standard C says nothing about this.

S.
 
K

Keith Thompson

paul c said:
I'm using microsoft visual c++ 6.0 compiler. My code is C, I just use
the c++ compiler for easier positioning of declarations here and there.

If you're mixing declarations and statements, your code isn't legal C
according to the C90 standard, but it probably is according to the C99
standard.

But note that compiling C code with a C++ compiler might cause some
problems. C isn't a strict subset of C++. The most obvious
difference is that C++ has some extra keywords; a variable called
"class" is perfectly legal in C, but not in C++. A more subtle
difference is the handling of void*. In C, a void* value can be
implicitly converted to any pointer-to-object type; in C++, it can't.
In particular, this:

some_type *ptr = malloc(sizeof *ptr);

is legal (and good style) in C, but a C++ compiler will complain about
a type mismatch.

If you don't have a C compiler that allows mixing declarations and
statements, you might consider just not mixing declarations and
statements. You can bring declarations closer to where they're used
with nested blocks.

[...]
Can anybody advise what compile options I might use to force a jump
table when a switch statement is compiled? If I have to use a
different compiler, I will. Also, is there a disassembler or somesuch
that will let me confirm that a jump table was produced?

I don't have an answer to that question (and if I did it would be
off-topic here). But it's probably not worth worrying about. If your
compiler is at all decent, it should do a reasonably good job of
generating the best possible code for a swtich statement. That might
not necessarily be a jump table. Use a command-line option to
increase the optimization level, and measure the actual speed of your
code; if it's fast enough, don't worry about it.

If you're sufficiently curious, most compilers have an option to
generate an assembly listing so you can examine the generated code.
Just remember that there's a good chance that the compiler knows more
than you do about the best code to generate.
 
P

paul c

Thanks to Keith T and Skarmander for those answers. (Although I'm not
an Intel assembler expert, even vc's debug output sometimes produces a
jump table but not always - my target is a single process through which
hundreds of users will access memory one at a time but potentially
millions of memory accesses each time a user calls it - function
pointers are safer from a coding point of view but my measurements
suggest they are pretty expensive for my limited use of their capabilities.)


cheers,
pc
 
M

Malcolm

Keith Thompson said:
If you're sufficiently curious, most compilers have an option to
generate an assembly listing so you can examine the generated code.
Just remember that there's a good chance that the compiler knows more
than you do about the best code to generate.
You can still normally beat a compiler with hand-optimised assembly. It's
quite a long time since I've had to do this, however.
 
P

paul c

Malcolm said:
You can still normally beat a compiler with hand-optimised assembly. It's
quite a long time since I've had to do this, however.


Could be an option, as I think there are only a couple of possible
processors for this program, basically generic Intel and Mac (which I
assume is still Motorola) and although I'd have to learn a bit of
assembler, for my purpose only a couple of dozen assembler lines are
needed provided they can be macro-ized.


Made up some more tests and the Visual C++ 6.0 jump table performance
didn't really outshine the function pointer alternative. Will have to
look more closely at the generated machine code.


thanks,
pc
 
C

Chris Torek

You can still normally beat a compiler with hand-optimised assembly. It's
quite a long time since I've had to do this, however.

It has, however, become quite a bit more difficult lately (in my
experience at least). This is not so much because the compilers
are better -- although they are -- but rather because the machines
are much worse, in terms of predictability. An "obvious" optimization
that results in half the number of instructions in the innermost
loop sometimes results in twice the number of cycles in the innermost
loop.

Worse, sometimes the most significant optimization is to place the
branch that closes a loop at a particular position within the cache
line(s), which can require counting up the bytes of instructions
leading up to that point. "Counting" is something computers are,
in general, better at than people.
 
N

Nathan Wagner

Worse, sometimes the most significant optimization is to place the branch
that closes a loop at a particular position within the cache line(s), which
can require counting up the bytes of instructions leading up to that point.
"Counting" is something computers are, in general, better at than people.

Cue the story of Mel, who, I am lead to understand, was a *real* programmer.
 
F

Flash Gordon

paul said:
Could be an option, as I think there are only a couple of possible
processors for this program, basically generic Intel and Mac (which I
assume is still Motorola) and although I'd have to learn a bit of
assembler, for my purpose only a couple of dozen assembler lines are
needed provided they can be macro-ized.

If the algorithm is optimised already, and the code is written sensibly
but still not fast enough, then this is probably the only reliable way
to get the required performance. After all, the next patch to the
compiler might change the way it handles the code you've written.
Made up some more tests and the Visual C++ 6.0 jump table performance
didn't really outshine the function pointer alternative. Will have to
look more closely at the generated machine code.

Which just goes to show why it is so often pointless trying to outsmart
the compiler with micro-optimisations.
 
K

Keith Thompson

Flash Gordon said:
If the algorithm is optimised already, and the code is written
sensibly but still not fast enough, then this is probably the only
reliable way to get the required performance. After all, the next
patch to the compiler might change the way it handles the code you've
written.

And the next version of the CPU might change the performance
tradeoffs. The patch to the compiler might be designed to generate
better code for the newer CPU; if you use assembly language, you can't
take advantage of the better generated code.

Use assembly if you must, but be prepared to throw it away later on.
If your assembly code is actually faster than the code generated by
the compiler, consider letting the compiler authors know about the
optimization they're missing (if it's likely to be generally useful).
Which just goes to show why it is so often pointless trying to
outsmart the compiler with micro-optimisations.

Indeed.
 

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,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top