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

Speed up CPU #20

Closed
ear7h opened this issue Nov 23, 2018 · 5 comments
Closed

Speed up CPU #20

ear7h opened this issue Nov 23, 2018 · 5 comments

Comments

@ear7h
Copy link
Contributor

ear7h commented Nov 23, 2018

Just found this project and saw one of you goals was to speed up the CPU, I think I found an optimization that can be made in the following function. Currently there is a switch statement but I think a lookup table in the form of a map[byte]func(*Gameboy) or [numOpCodes]func(*Gameboy) (static size array) would be more efficient.

// ExecuteOpcode is a large switch statement containing the opcode operations.
func (gb *Gameboy) ExecuteOpcode(opcode byte) {

@ear7h
Copy link
Contributor Author

ear7h commented Nov 23, 2018

Quick update:
Currently working on a PR for this issue, I have the following references which shed some light on the subject. Also it looks like the handling of the CB instruction can benefit slightly by using static arrays.

Array access optimization
https://stackoverflow.com/a/43942734

Golang issue tracking jump tables
golang/go#5496

@Humpheh
Copy link
Owner

Humpheh commented Nov 23, 2018

Hey @ear7h, this is really interesting. I've thought about using this method before but never got around to benchmarking it.

It would be great if we could compare the three methods of doing it. From recent experience with optimising the PPU I'm pretty sure that [numOpCodes]func(*Gameboy) would end up being quicker than map[byte]func(*Gameboy) as I found the mapaccess1 to be a large overhead (probably due to the hashing), and as the opcodes are all integers up to 0xFF I can't see a reason not to use the array.

I think it would be good to find some of the places where slices are used instead of arrays - I imagine there are a few cases where I have done this.

@ear7h
Copy link
Contributor Author

ear7h commented Nov 23, 2018

My PR has the array table, I proposed a map becasue I wasn't sure how dense the op codes were (never worked with emulators before). The PR doesn't have any benchmarks, is there any resources you know to make this easier? I tried finding some sort of benchmarking ROM but a cursory search didn't yield anything.

@Humpheh
Copy link
Owner

Humpheh commented Nov 25, 2018

Thats fair, thanks for contributing! There is a builtin benchmarking library into go which is good to use. I added a benchmark to #21 which just randomly calls opcodes on a blank rom. I feel like that gets a good example of the switch/array performance even if it doesn't fully exercise the opcode functionality.

@Humpheh
Copy link
Owner

Humpheh commented Dec 27, 2018

Closing as this was implemented in #21.

@Humpheh Humpheh closed this as completed Dec 27, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants