Some questions
Guillermo Adrián Molina
guille at losmolina.com.ar
Thu Apr 26 15:37:30 UTC 2007
> Guillermo Adrián Molina writes:
>
> > Ok!, tried that, it worked:
> > 668407310 bytecodes/sec; 13559830 sends/sec
> > 760772659 bytecodes/sec; 13803237 sends/sec
> > 777524677 bytecodes/sec; 12762744 sends/sec
> > 760772659 bytecodes/sec; 13834279 sends/sec
> > 775757575 bytecodes/sec; 13569800 sends/sec
> > I read something about intel being faster than AMD for exupery, Do you
> > know why is that?
> >
>
> Exupery was much faster than the interpreter on Pentium 4s. That's
> because the Pentium 4 is an inefficient chip to run the interprter on.
>
> Those comparisions are rather old now. Hardware has moved on and so
> has Exupery. Benchmarking now with bigger suites may show different
> numbers.
>
> > > > 4) In my experiments with exupery, I get an error if I inline too
> many
> > > > methods. I think I am getting out of machine registers, for
> example,
> > > when
> > > > I try to compile Integer-#digitDiv:reg:.
> > > > I get this error In the ColouringRegisterAllocator phase, but it
> is not
> > > a
> > > > "You dont have more registers, dude" kind of error.
> > > > Is the "no more registers" situation taken into consideration?
> > >
> > > I'd guess that it was because a variable was live at an entry point.
> > > There's a stack tracing bug which I'm just fixing that could have
> > > caused that.
> > >
> > > I use the liveness analyser in the register allocator to catch
> > > compiler bugs. It's much nicer to catch them there than with crashes.
> > >
> >
> > Yes I've seen those kind of errors (variable live at entry point),
> > corrected them initializing temps with nil.
> > I think this is something different. In this method of the
> > ColouringRegisterAllocator:
> >
> > findNodeToSpill
> > | spillable |
> > "This is just a basic heuristic, spill the register that interferes
> with
> > the most
> > other registers. It is possible to do a lot better.
> > The heuristic should concider how much each register is used while it
> is
> > alive"
> > spillable := spillWorklist select:
> > [:each | ((self hasSpill: each register) not) and: [each register
> > isMachineRegister not]].
> > spillable := spillable asSortedCollection: [:a :b| a spillWeight > b
> > spillWeight].
> > ^ spillable first
> >
> > After compiling lots of methods using exupery, it fails with very big
> > methods because spillable is nil, and spillable first throws an error.
> If
> > I make less inlining (for example, not inlining divisions and
> > multiplications), it compiles ok!
> > Any ideas?
>
> I'd guess it's a limit with the register allocator. It is possible
> that it can fail to find a register to spill when it needs to spill
> something. Given this bug will not cause crashes or incorrect
> execution it's not high priority.
>
> > > > 5) Is there a way to implement indirect jump tables in exupery?
> > >
> > > It would be possible. I do use indirect jumps for returns to compiled
> > > methods. If you look at any method you should see at least one
> > > indirect jump in the return code. Just jump to a register.
> > >
> > Yes, I checked that, but I still need to initialize that register with
> the
> > convenient block, but I need to do that without using Jcc (conditional
> > jumps) to choose from the right one, Any suggestions?
>
> Exupery also can get the address of a block. That's also done in the
> send code to save the compiled program counter. The compiled program
> counter is the address of the machine code block to return to encoded
> as a SmallInteger. Return blocks are aligned to 2 byte boundaries to
> allow for tagging. That's enough to build an indirect jump table if
> you wanted to do that.
>
Yes I also notice that, using MedAddress, right?
Forgive me, but I still can't get the point:
For example:
MedMov
from: (MedAddress addressOf: blockN)
to: aMedReg
MedJump
type: #jmp
target: aMedReg
block1:
do something1
jmp end
block2:
do something2
jmp end
block3:
do something3
end:
this could be a jump table,
But I still need to select which block to jmp.
The only way of selecting the block I can Imagine is nesting compares,
something with jumps like:
MedJump
type: #jc
target: aLabel
instruction: (MedComparision
operator: #bitTest
arg1: aMed
arg2: (MedLiteral literal: 0))).
But I want to implement a jump table to avoid conditional branching
> Why do you need to build an indirect jump table? What are you trying
> to do?
>
I am implementing a smalltalk. It compiles directly to machine code, with
exupery. The last time I asked something to the list I was starting to use
exupery. Now I am almost done with that (without many optimizations). I am
doing unit testing right now.
My first mail to the list asked what would be the best to implement a new
st, so, in my implementation I use:
0 tagged ints.
A simple (and a little fat) object memory.
A very straightforward send mechanism (with C calling convention for
calling methods).
No contexts, but using BlockClosures (frames are the same as in C, the C
compiler does not differentiate C code from ST code).
I compile the ST code from .st files to .s (assembler) using SmaCC,
RefactoryBrowser, and then exupery, I still need squeak in order to run
all that.
I only use the bottom layer of exupery, (does not use IntermediateXXXXXX
classes)
I implemented the cmovxx instruction in exupery, because it is very useful.
But I need jump tables to implement for example, faster versions of
ifTrue:ifFalse:, and a lot of other things. This could lead to faster
results.
Right Now I am getting (with the same machine), tinyBenchmarks:
Squeak: 172043010 bytecodes/sec; 5468700 sends/sec
Squeak/Exupery: 775757575 bytecodes/sec; 13569800 sends/sec.
myST/Exupery: 1072251308 bytecodes/sec; 36056442 sends/sec
> Bryce
> _______________________________________________
> Exupery mailing list
> Exupery at lists.squeakfoundation.org
> http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/exupery
>
Cheers
Guille
More information about the Exupery
mailing list