Mass performance improvements through data profiling.
Moderator: ZSNES Mods
Mass performance improvements through data profiling.
For several years I have sought to counter the claim SPC files must be recorded, not ripped, from SNES ROM files. Because the DSP can accept instruction from any point within ROM, the argument has been made that it is impossible to delineate sound data from other data. I no longer believe this to be true.
A code profiling routine could search an entire ROM for instructions that refer to specific hardware components, like the tile tables, the sound DSP, the SuperFX chip, the C4, etc. and with the understanding that those hardware components can only work with specific forms of data (e.g. sound, video), recognize all of the data that will be needed at any point in the game by any one hardware component. Searching the ROM instruction memory for DSP hardware references, a code profiler could index every bit of information on the ROM that will be used for sound into memory ahead of time, and, at the whim of the user, filter all of the sound memory when the ROM is loaded, precluding the need for the sound to be filtered at runtime by the CPU. Every time a filter is activated or deactivated by the user, whether it be a resampler, a Gaussian interpolation, or a HQ2x vectorizer, the profiler respective to the effected hardware could be run again, to update the hardware's data-in-wating as it lied in memory.
With data profiling precalculation, runtime CPU resources may be devoted anew to the act of emulation, as opposed to improving the apparent quality of the presentation. I understand that a code profiler would be a long, hard project to implement, but if it were done just once, I imagine that it could scale to the source of any emulated hardware and thereby increase indefinitely all emulation performance. I will work to design an algorithm for the profiler, if that will be helpful.
A code profiling routine could search an entire ROM for instructions that refer to specific hardware components, like the tile tables, the sound DSP, the SuperFX chip, the C4, etc. and with the understanding that those hardware components can only work with specific forms of data (e.g. sound, video), recognize all of the data that will be needed at any point in the game by any one hardware component. Searching the ROM instruction memory for DSP hardware references, a code profiler could index every bit of information on the ROM that will be used for sound into memory ahead of time, and, at the whim of the user, filter all of the sound memory when the ROM is loaded, precluding the need for the sound to be filtered at runtime by the CPU. Every time a filter is activated or deactivated by the user, whether it be a resampler, a Gaussian interpolation, or a HQ2x vectorizer, the profiler respective to the effected hardware could be run again, to update the hardware's data-in-wating as it lied in memory.
With data profiling precalculation, runtime CPU resources may be devoted anew to the act of emulation, as opposed to improving the apparent quality of the presentation. I understand that a code profiler would be a long, hard project to implement, but if it were done just once, I imagine that it could scale to the source of any emulated hardware and thereby increase indefinitely all emulation performance. I will work to design an algorithm for the profiler, if that will be helpful.
-
- Devil's Advocate
- Posts: 2293
- Joined: Mon Aug 02, 2004 7:51 pm
- Location: Hmo. Son.
Re: Mass performance improvements through data profiling.
Well, if you think that you can do it, start working on it, I think the developers will appreciate any help given. Thanks for the help. There are people here that can help you, sadly I know next to nothin about this stuff.lordgalbalan wrote:I will work to design an algorithm for the profiler, if that will be helpful.

*Sometimes I edit my posts just to correct mistakes.
-
- Romhacking God
- Posts: 922
- Joined: Wed Jul 28, 2004 11:27 pm
- Contact:
I don't think that's going to work. Give me a specific example of how you would 'profile' code for the SPC or anything for that matter?
You'd have to look for opcodes that signify loading SPC data or something like that. What happens when say text or graphics data happens to have the same sequence of bytes? What then? There are many things in a ROM besides code and there is no way to seperate what is code and what is data.
I doubt you would ever be able to get it to accurrately detect ALL instances of SPC loading in a ROM correctly.
You'd have to look for opcodes that signify loading SPC data or something like that. What happens when say text or graphics data happens to have the same sequence of bytes? What then? There are many things in a ROM besides code and there is no way to seperate what is code and what is data.
I doubt you would ever be able to get it to accurrately detect ALL instances of SPC loading in a ROM correctly.
[url=http://transcorp.romhacking.net]TransCorp[/url] - Home of the Dual Orb 2, Cho Mahou Tairyku Wozz, and Emerald Dragon SFC/SNES translations.
[url=http://www.romhacking.net]ROMhacking.net[/url] - The central hub of the ROM hacking community.
[url=http://www.romhacking.net]ROMhacking.net[/url] - The central hub of the ROM hacking community.
You would have to start at the beginning of the code segment, and use a decision-free emulation algorithm to trace through every segment of the code, following all break instructions only once and without respect to the conditions of the break. In so doing, it would be possible to traverse every single line of executable code in ROM.
The sound DSP uses specific register numbers. At every offset whereat the registers numbers for the DSP were loaded in code, conditional breaks in the vicinity of the offset would be valid. Memory copy routines would function normally, and the sound data destined for the DSP could instead be redirected to RAM until it is called for by the full emulator.
The sound DSP uses specific register numbers. At every offset whereat the registers numbers for the DSP were loaded in code, conditional breaks in the vicinity of the offset would be valid. Memory copy routines would function normally, and the sound data destined for the DSP could instead be redirected to RAM until it is called for by the full emulator.
-
- Romhacking God
- Posts: 922
- Joined: Wed Jul 28, 2004 11:27 pm
- Contact:
Ok.. so you're going through code and then when you hit a branch you execute all code on BOTH possible branch locations?
Assuming you now do go through every line of code, I still see a problem.
Take this scenario:
You have ONE sound routine for the entire game. You just feed it different offsets to where your SPU data is stored.
By your technique, you would hit this routine to load up the DSP registers for the first song and that's it.
In the real game, this routine is hit MANY times with different offsets each time new data is loaded. You will not be able to rip more than one song from the ROM.
I just can't see how this idea can ever work. Even if you now say you will emulate the game to hit the routine more than once, you have no way to simulate controller input etc.. to meet conditions necessary for the next song to be loaded.
Assuming you now do go through every line of code, I still see a problem.
Take this scenario:
You have ONE sound routine for the entire game. You just feed it different offsets to where your SPU data is stored.
By your technique, you would hit this routine to load up the DSP registers for the first song and that's it.
In the real game, this routine is hit MANY times with different offsets each time new data is loaded. You will not be able to rip more than one song from the ROM.
I just can't see how this idea can ever work. Even if you now say you will emulate the game to hit the routine more than once, you have no way to simulate controller input etc.. to meet conditions necessary for the next song to be loaded.
[url=http://transcorp.romhacking.net]TransCorp[/url] - Home of the Dual Orb 2, Cho Mahou Tairyku Wozz, and Emerald Dragon SFC/SNES translations.
[url=http://www.romhacking.net]ROMhacking.net[/url] - The central hub of the ROM hacking community.
[url=http://www.romhacking.net]ROMhacking.net[/url] - The central hub of the ROM hacking community.
The controller input is irrelevant. Controller input may only be analyzed by branching, you know this.Nightcrawler wrote:In the real game, this routine is hit MANY times with different offsets each time new data is loaded. You will not be able to rip more than one song from the ROM.

...By the way, I've been studying the Japanese alphabet a bit, and I think I've got a slight handle on Romanji/Katakana/Hirogana. If my fledgling experience with the Japanese language can be of help, then I gladly offer my services.
-
- Rookie
- Posts: 42
- Joined: Wed Aug 18, 2004 10:15 pm
-
- Romhacking God
- Posts: 922
- Joined: Wed Jul 28, 2004 11:27 pm
- Contact:
Right.. controller input is analyzed by branching. I wasn't thinking along those lines. Controller input was not a good example. I was trying to think of a type of thing that would only happen by actually running the game that can't really be handled by just analyzing the code.lordgalbalan wrote:The controller input is irrelevant. Controller input may only be analyzed by branching, you know this.Nightcrawler wrote:In the real game, this routine is hit MANY times with different offsets each time new data is loaded. You will not be able to rip more than one song from the ROM.Even interrupt invocation involves momentary branching. If you examine the entire code tree, then you come across every used offset in the course thereof. It is impossible to use a value in code that has not been explicitly declared at some point therein, unless that value is received from an external source, like loading a register with either 1 or 2 depending on which button is pressed. Even then, its case must be dealt with in code. ...To reinforce my point, I will present a case study of this algorithm as it would function on the NES 6502 CPU/sound chip.
How about this scenario; Would you have a problem with loops?
You've got a loop, it's being executed say 100 times. The only branch instruction just checks to see if the loop has been executed 100 times. Now.. during each iteration of the loop, a running sum is generated in some way. After the loop is finished, that running sum becomes an offset for sound data.
There is no way you would arrive at this offset by simply analyzing all code and branches. Since there NO condition which checks this running sum, the ONLY way to arrive at the offset would be to run through the loop.
How would you handle something like that? That's the only specific case I can think of off the top of my head, but I think there would be other cases where an offset is generated and there is NO branch instruction or condition that checks it.
I appreciate the offer, but unfortunately to be useful on the translating side of things, you need to be quite fluent in Japanese. I actually also have a translator for most of my projects right now which is rare these days....By the way, I've been studying the Japanese alphabet a bit, and I think I've got a slight handle on Romanji/Katakana/Hirogana. If my fledgling experience with the Japanese language can be of help, then I gladly offer my services.
On the hacking side of things though, I could probably use extra help if your skills were decent in that area.
[url=http://transcorp.romhacking.net]TransCorp[/url] - Home of the Dual Orb 2, Cho Mahou Tairyku Wozz, and Emerald Dragon SFC/SNES translations.
[url=http://www.romhacking.net]ROMhacking.net[/url] - The central hub of the ROM hacking community.
[url=http://www.romhacking.net]ROMhacking.net[/url] - The central hub of the ROM hacking community.
Hmm... I see the scenario, but is there even such a routine in existence? It seems kinda useless for something as straightforward as data storage. Anyway, let's consider this in 6502 native code, to get some insight.You've got a loop, it's being executed say 100 times. The only branch instruction just checks to see if the loop has been executed 100 times. Now.. during each iteration of the loop, a running sum is generated in some way. After the loop is finished, that running sum becomes an offset for sound data.
There is no way you would arrive at this offset by simply analyzing all code and branches. Since there NO condition which checks this running sum, the ONLY way to arrive at the offset would be to run through the loop.
How would you handle something like that? That's the only specific case I can think of off the top of my head, but I think there would be other cases where an offset is generated and there is NO branch instruction or condition that checks it.
Code: Select all
; Load 100 (64 hex) into the X index register.
; Clear the accumulator.
LDX #$64
LDA 0
Test:
; Decerement the X register
DEX
; Increment the accumulator
INA
; Is the X register at 0? If not, repeat the loop.
BNE Test
; Load the byte at the address pointed to by the accumulator into Y
LDY [A]
Sure thing!On the hacking side of things though, I could probably use extra help if your skills were decent in that area.

-
- Romhacking God
- Posts: 922
- Joined: Wed Jul 28, 2004 11:27 pm
- Contact:
Sure, there are plenty of routines that calculate offsets based on loops in simalar way. The most common reason for doing this is to find something in a lookup table. You can have a table of offsets to be loaded and in fact, most games do.lordgalbalan wrote:Hmm... I see the scenario, but is there even such a routine in existence? It seems kinda useless for something as straightforward as data storage.You've got a loop, it's being executed say 100 times. The only branch instruction just checks to see if the loop has been executed 100 times. Now.. during each iteration of the loop, a running sum is generated in some way. After the loop is finished, that running sum becomes an offset for sound data.
There is no way you would arrive at this offset by simply analyzing all code and branches. Since there NO condition which checks this running sum, the ONLY way to arrive at the offset would be to run through the loop.
How would you handle something like that? That's the only specific case I can think of off the top of my head, but I think there would be other cases where an offset is generated and there is NO branch instruction or condition that checks it.
Yeah, that routine is a basic example of what I was trying to say.Anyway, let's consider this in 6502 native code, to get some insight.
I think that does the job. I see what you mean though. Definitely, the issue is far more complex than it at first appears. What if the accumulator is itself dependent on a previous loop? ...In any case, it is possible to determine that there is no escape from the loop in this instance except to pursue it in its entirety, so this loop could be determined as a necessity to execute. ...Isn't that a fully effective solution? I think so... not when you look at it just for quick critique, it doesn't seem like it is. But when you examine the limitations under which the possible critique could actually transpire, I think that this conclusion covers all of the bases.Code: Select all
; Load 100 (64 hex) into the X index register. ; Clear the accumulator. LDX #$64 LDA 0 Test: ; Decerement the X register DEX ; Increment the accumulator INA ; Is the X register at 0? If not, repeat the loop. BNE Test ; Load the byte at the address pointed to by the accumulator into Y LDY [A]
Yes, the accumlator entering a loop is often times already initialized by some other routine or loop. Ok, you say it's possible to determin e which loops are and are not necessary to execute? That's a pretty bold statement. What if the loop before this loop that generated the accumlator value was one of the loops that wasn't necessary to execute?
Take this case also.. the result of this loop points to an offset in a lookup table of offsets to the song data. What I mean by this is you have a table of 10 offsets for each of your 10 songs. Even if you do exectute, the loop, you won't get all 10 offsets. You'd have to know there was a table involved and read ALL offsets of the table.
I think you're opening up a huge can of worms that isn't going to a managable program.
Loop accumulator starting values can be based on the previous 3 loops or the past several routines that are not in any particular order.
You're going toh ave to keep track of mammoth amounts of information and branch points.
I'm surprised that absolutely no one else on this board has any input to this conversation. I'd like to hear some opinions of other knowledgable people on this topic.
Sure thing!On the hacking side of things though, I could probably use extra help if your skills were decent in that area.

Send me an e-mail with a summary of your skills. What you know, and what you have done in terms of romhacking. I need to assess your ability so I know what kind of tasks I could give you.
[url=http://transcorp.romhacking.net]TransCorp[/url] - Home of the Dual Orb 2, Cho Mahou Tairyku Wozz, and Emerald Dragon SFC/SNES translations.
[url=http://www.romhacking.net]ROMhacking.net[/url] - The central hub of the ROM hacking community.
[url=http://www.romhacking.net]ROMhacking.net[/url] - The central hub of the ROM hacking community.
-
- Savestate Pimp
- Posts: 129
- Joined: Thu Jul 29, 2004 2:15 pm
- Contact:
You already said it:Nightcrawler wrote:I'm surprised that absolutely no one else on this board has any input to this conversation.
Nightcrawler wrote:I think you're opening up a huge can of worms that isn't going to be a managable program.
Edit: fixed.
Last edited by illegal eagle on Fri Sep 17, 2004 5:49 pm, edited 1 time in total.
"Other people can give you more suggestions as I just lost all my motivation to respond further to this post."
[i] - Nightcrawler[/i]
[url=http://www.geocities.com/illegal_eagle_2003/]vSNES v2.00[/url]: My SNES savestate viewer.
[i] - Nightcrawler[/i]
[url=http://www.geocities.com/illegal_eagle_2003/]vSNES v2.00[/url]: My SNES savestate viewer.
-
- Romhacking God
- Posts: 922
- Joined: Wed Jul 28, 2004 11:27 pm
- Contact:
You have an uncanny ability to quote me when I either misspell words, skip words, or made some other mistake!
How do you do it man? I don't make them that often, but you find them.
How do you do it man? I don't make them that often, but you find them.
[url=http://transcorp.romhacking.net]TransCorp[/url] - Home of the Dual Orb 2, Cho Mahou Tairyku Wozz, and Emerald Dragon SFC/SNES translations.
[url=http://www.romhacking.net]ROMhacking.net[/url] - The central hub of the ROM hacking community.
[url=http://www.romhacking.net]ROMhacking.net[/url] - The central hub of the ROM hacking community.
-
- Savestate Pimp
- Posts: 129
- Joined: Thu Jul 29, 2004 2:15 pm
- Contact:
I didn't notice it, again. Happens when you're knowing what the writer's saying, and jump over sentence parts.
Maybe your spell checking is disabled when you post thoughtful stuff.
Maybe your spell checking is disabled when you post thoughtful stuff.

"Other people can give you more suggestions as I just lost all my motivation to respond further to this post."
[i] - Nightcrawler[/i]
[url=http://www.geocities.com/illegal_eagle_2003/]vSNES v2.00[/url]: My SNES savestate viewer.
[i] - Nightcrawler[/i]
[url=http://www.geocities.com/illegal_eagle_2003/]vSNES v2.00[/url]: My SNES savestate viewer.