Guillermo Adrián Molina writes:
In Exupery the SmallInteger addtion sequence is bitTest arg1 jumpIfSet failureBlock bitTest arg2 jumpIfSet failureBlock clearTagBit arg1 add arg1 arg2 jumpOverflow failureBlock
The failure case is a full message send.
The problem with the above code is that you have 3 branches. That is why I need jump tables, there are cases where cmov really
dosn't help
There is only 3 branches and I'm hoping that they will never be taken so they should be easy to predict. That said the branches do use branch predictor resources which could cause other branches not to be predicted as well.
Yes, I agree. I am really not an expert int this matters, but I think It is not so uncommon to send #+ with other objects than smallints, in that case, may be one of the first 2 branches would be misspredicted. May be you could test that both of them are smallints with just one branch. (I am doing that right now). But may be I will try to do it without branching at all
Before I started using exupery, I called special methods in C that implemented faster code. Every special method (and primitives) returned
1
in case of an error, and if success, returned the result object. One of this special methods was +. This is part of the code:
if(areIntegers(rcvr,arg)) { int result; asm( "movl $1,%%edx\n\t" "movl %[rcvr],%[result]\n\t" "addl %[arg],%[result]\n\t" "cmovol %%edx,%[result]" : [result] "=r" (result) : [rcvr] "r" (rcvr), [arg] "r" (arg) : "edx" ); return result; }
with this code, I've got up to 10% faster code in + intensive tests.
Do you have conditionals inside areIntegers and to check if the result is 1 indicating an error?
As I dont use this code so often as before, (because I inline that with exupery at compile time) I dont't worry about it any more. But areIntegers() is just an "or" and an "and", the branch is represented in the C "if" statement. I wrote the addition that way because I wanted to test if cmov was really that fast. It was better, but not THAT better.
Guille