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