Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

core/vm: avoid copying jumptable #21180

Closed
wants to merge 1 commit into from

Conversation

holiman
Copy link
Contributor

@holiman holiman commented Jun 5, 2020

cfg.ExtraEips = append(cfg.ExtraEips[:i], cfg.ExtraEips[i+1:]...)
log.Error("EIP activation failed", "eip", eip, "error", err)
}
var jt *JumpTable
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a nicer way to do this: if you change the type of jt to just JumpTable, you don't need to have all those &s below and you remove the extra copy in the loop below.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if that defeats the optimization though :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that defeats the entire purpose of the PR... ?

Copy link
Contributor

@fjl fjl Jun 5, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, but you do have to copy it when there are ExtraEips. The previous
version did multiple copies. If you apply my suggestion, there will be exactly
one copy. Can't really avoid that one if you want to be able to modify the instruction set before executing.

I'm really wondering about the performance impact of this change.
I think the idea is to speed up NewEVMInterpreter, but AFAIK that's not
really the bottleneck for anything.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Anyway, you can disregard my comment. We should still measure what the impact of this is, can't be that much.

@@ -225,7 +222,7 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (
// Get the operation from the jump table and validate the stack to ensure there are
// enough stack items available to perform the operation.
op = contract.GetOp(pc)
operation := in.cfg.JumpTable[op]
operation := &in.jt[op]
Copy link
Contributor

@fjl fjl Jun 5, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If there is any performance gain, it's likely from this change instead of the change in NewEVMInterpreter because this statement executes every instruction.

@karalabe
Copy link
Member

karalabe commented Jun 5, 2020 via email

@holiman
Copy link
Contributor Author

holiman commented Jun 5, 2020 via email

@karalabe karalabe added this to the 1.9.16 milestone Jun 8, 2020
@karalabe
Copy link
Member

karalabe commented Jun 8, 2020

I ran my SnailTracer benchmark against master vs. this PR, and there's a ~5% EVM number crunching speed improvement. It's not "amazing", but it's definitely noticeable.

@karalabe
Copy link
Member

karalabe commented Jun 8, 2020

Though I don't see an allocation difference, so not sure if there's actually something better or if it's just benchmarking fluke

@fjl fjl modified the milestones: 1.9.16, 1.9.17 Jul 10, 2020
@karalabe
Copy link
Member

I've played with this PR a bit and a few things I've learned:

  • There's absolutely no difference in the allocation count. Maybe @AlexeyAkhunov 's optimization was only needed for an older version of Go.
  • The PR was a tiny bit faster than master, so I investigated @fjl's suggestion that it might be that one pointer retrieval. It indeed was for some reason (or it seemed 4ms faster snail tracing (304ms in total, so not spectacular)).
  • I've wondered what happens if I change the type of the JumpTable from [256]operation to [256]*operation, thinking that Go might be doing some copies in tight loops in vain. The runtime of the snail tracer dropped 16ms compared to master, to 292ms.

All in all I think we can close this PR as it does not save any allocs whatsoever and seems to change code that's noop and open a new PR with the operation pointer optimization.

@karalabe
Copy link
Member

This is my alternative PR that performs even better than this one #21336

@holiman holiman closed this Jul 16, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants