GP2X Virtual Rom


DijiTao

Active Member
Joined
Aug 4, 2005
Messages
572
In my thread “Question About Neo Geo Mvs Emulation” (http://www.gp32x.de/board/index.php?showtopic=21613) I eventually reached the conclusion that the best hope for dealing with ROMs larger then what the GP2X can fit into RAM was to implement a caching system that would keep as much of the ROM in RAM as possible, and hopefully the part of the ROM in RAM was what was actually most likely to be used. I think if any of you devs where watching that thread you would have stopped however before I reached that point since the replies where getting a bit off topic. This PDF goes over some of the techniques used in virtual memory page replacement which is a very similar concept:

http://people.msoe.edu/~mccrawt/resume/pap...384_virtual.pdf

What we need is Proximity Based Caching coupled with Least Recently Used (LRU) Replacement. I explained what I meant by Proximity in the previous thread so here’s a quote:

”DijiTao” said:
Predictably load and release parts of the NeoGeo’s rom to and from RAM. Something as simple as proximity should be effective enough for this to work since the data on the cartridge is stored in a somewhat logical manner. What I mean by this is a system like the following, picture the alphabet as the entire contents of the ROM. If we need Q, W, and C you would get something like the following:

SD: A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
RAM: A B C D E O P Q R S U V W X Y

When new data needs to read in some old data needs to be released and LRU replacement seems about as good as it’s going to get.

So my question to you devs are:

Does this approach sound feasible?
Do you think it will solve the problem?
What problems do you foresee in a system like this?
Does anyone have any experience with this sort of thing?
Does anyone think they could implement this?
 
Last edited by a moderator:
Funny, I just finished taking a class on Operating Systems, and one of the major topics we covered was Paging & virtual memory management.

Turns out the linux kernel inherently supports a mechanism for virtual memory (hence the need for linux "swap" partitions), which uses an "age"-based system for keeping track of which pages (sections of memory that can be moved between RAM and ROM) should be kept in RAM, and which ones can be moved back to ROM.

The first thing that comes to mind would just be to partition your SD card into a swap partition and a main data partition, and then modify the kernel slightly to point it to the SD card to use as its swap. This seems to be the simplest solution to me, as you dont need to worry about re-inventing the wheel when it comes to virtual memory management, just let the linux kernel handle it.

The difficulties I see happening with this approach (I think all can be overcome however)
1) Transfer time between the SD card and RAM (however this should be faster than a normal Hard Driver, so on second though that shouldnt be an issue)

2) I"m not sure if the MMSP2 and its kernel was modified in this respect. A standard linux kernel should have this built in, but GPH, if it wasnt using it, could be taking it out of the kernel as unnecessary overhead.

3) if they are keeping it in, it might be because they're using some of the NAND memory as swap. Switching this to SD, it would likely be slower, which might degrade the GP2X's overall performance, if it is used a decent amount. However, this would have the side effect of freeing up that ROM currently used for swap. I would think looking into mounting both of them as swap would be a better idea, however (possible in linux), see point #4 for why I think this is the case.

4) biggest issue I see. You would not be able to swap SD cards while the system was running. A well-made modification to the OS would mean that it would check to see if the SD card had a swap space at startup, and use only the NAND memory if it wasnt present (2x then functions as normal), and if it did have a swap partition, potentially mount both as swap (possible). This would mean that the swap on the SD card would have to be unmounted before you could remove the card, or bad, bad things would happen. I honestly have never heard of a situation where swap partitions are mounted/unmounted on the fly, so I dont know how possible this would be. The result, if it isnt feasible, would be that you'd have to have your SD card in when you first turned the console on, and leave it in the entire time the console is on. Not a huge issue, but could be annoying.

Is this the best solution? I have no idea. It does seem feasible, however, if GPH didnt mess with the kernel too much, and if we can have access to and modify some of the swap mounting routines. I personally know how linux swaps out the differnet pages, etc, but I dont know how to tell it which partition to use as swap, etc. Any linux gurus want to speak up on this note?
 
Well speed shouldnt be the big issue, and mounting/unmounting swap on the fly also works, on the gamecube you even run swap over network and mount it on the fly, the gamecube only haves about 48mb of ram (part of it aram) and it can run neogeo, however as the swap is awfull slow over network you have huge "lags" when playing bigger roms.
The thing that would worry me is the drastical reduced lifetime of the sd card when used for swap.
 
I'm fairly certain he's not talking about virtual memory/swap here guys. That idea has been pooh-poohed more than once because of the limited write cycles of SD cards and the NAND memory in the GP2X. He's talking about caching certain parts of the rom that will be needed as they'll be needed so that an entire NeoGeo MVS game does not need to be in RAM at all times. However, it seems that he's getting inspiration from methods used for virtual memory.

I don't have anything to add to your ideas Diji since I don't know enough about that stuff to be helpful. Good luck though!
 
Does this approach sound feasible?
Yes, you're basically building a virtual memory system in software.

Do you think it will solve the problem?
Yes, this will solve the problem.

What problems do you foresee in a system like this?
None, that I can think of.

Does anyone have any experience with this sort of thing?
Yes, I have extensive experience coding data streaming/caching systems for consoles. On those systems you got much more data on the DVD than you can fit into memory. True, the access is via file I/O rather than memory accesses, but the operation of the LRU/caching system is very similar to a virtual memory system.

Does anyone think they could implement this?
I could implement it. I've already got a game data streaming library that will handle streaming and caching data from the SD cards into GP2X RAM. The SD cards will stream data at 12Mb/s which is far slower than ROM access so you have to treat it more like a DVD-ROM than chip-based memory. My library would easily enable this kind of system to be built into an emulator.

Suggestion:
One thing you may want to do to improve the performace of your emulator is to have a second "speculative" thread that executes ahead of the main thread of execution to figure out where the ROM will be reading from in the near future and prefetching those pages before you need them.

Basically, anytime you get a page miss from your ROM code, you're going to have to flush the LRU page in RAM, go out to the SD card and stream in the missing page. There will be tons of CPU cycles wasted just waiting for the data to come in off of the SD card. It is during that down time that you should copy the existing register file and stack to configure your speculative thread. It will then continue in the background as if the blocking read from the SD card had already completed.

Any time the speculative thread sees a memory read instruction in the ROM code it would check against the state of the page cache and determine if the read will cause a page miss or not. If it will cause a page miss then the speculative thread should prefetch the page so that when the main thread resumes and gets to that bit of code, the page will already be in RAM.

Operating systems do this to improve file I/O to/from HDD's. I've seen numbers that range from a few percent up to 50%-60% improvement in performance. It make total sense to apply it to emulators since you've got a ready made sandbox that can easily peak at the next bit of ROM code to predict it's memory access pattern.

I hope this helps.
 
Last edited by a moderator:
If you could somehow just read what you need at the moment from the SD card into RAM then the lifespan of the card shouldn't hurt right? The games shouldn't need to write to more then 64MB right? There has to be some way to stream things. Anyway, that technical stuff is above my head so don't bother about me if I'm wrong :)
 
when only reading from sd lifetime wouldnt be the problem, its done in a simmilar way in gpa, the mmu is pretty usefull for such things.
but when you utilize the swap system of linux you will have tons of writes, thats why swap is a bad idear.
 
The thing that would worry me is the drastical reduced lifetime of the sd card when used for swap.
You guys are missing a critical point. You don't need to save the LRU pages back to the SD card. You can just flush it from memory and forget about it. The emulator is accessing ROM (read-only memory). The ROM code won't be modifying any data in the ROM memory so there is no need to save the flushed pages back to the SD card. If a page gets flushed from memory and then accessed again later, you just reload that page from the SD card.

The only thing you would need to worry about is if the game system that you are emulating has more RAM than the GP2X. I'm not aware of any that did however. Even the PS2 only has 32MB of RAM.
 
Last edited by a moderator:
when only reading from sd lifetime wouldnt be the problem, its done in a simmilar way in gpa, the mmu is pretty usefull for such things.
but when you utilize the swap system of linux you will have tons of writes, thats why swap is a bad idear.
And that's one good reason to implement the streaming/caching system yourself.
 
Last edited by a moderator:
Thanks for the reply MiniMoose - I'm not really a dev myself, I can code a little but this is all well beyond my ability. I just hope to be able to contribute to GP2X development by getting ideas out there, and hopefully doing a little straight forward porting work. I wrote this reply up before I read yours, the DVD analogy is perfect.

---

I guess I haven’t made my case clear enough for why this is similar two, but yet different from traditional swap.

We have a finite number of writes that can be preformed to the SD card or the Internal NAND memory, so we want to avoid repeatedly writing as that will kill the memory. Swap works by taking what’s in RAM that’s hasn’t been used recently and writing it to disk so something more likely to be used can be put into RAM. In the case of a ROM we already have what we want written to disk so writing it to disk again in the swap partition makes no sense as this consumes time and wears the SD card out. Unlike swap which has to accommodate for reading and writing, what we need is a solution that is read only, hence the moniker “Virtual ROM”. So our solution will be similar to swap in terms of how it decides what is retained in RAM and what is read from the disk, but it is different because it would never have to write to the disk as what is “swapping out” is already there. The next part why this is different is how things get placed in RAM to begin with. Using swap, the emulator would work as it already does by attempting to place the entire ROM into RAM and when there isn’t enough room it the beginning of the ROM and swaps it to the disk making enough room for the end of the ROM. However once the emulator starts execution it’s going to need the beginning of the ROM but unfortunately that’s going to have to be read from the disk again. Once things get going I would expect these misses to happen quite frequently as the swapping mechanisms aren’t going to do a very good job of knowing in advance when it should be pulling something into RAM. Take for example Garou, using swap, it would certainly run but when you do a move for the first time it’s going to have to load the graphics for it from the SD card because it wouldn’t have had any reason to give that bit of data priority over things it had previously loaded. If however you gave priority based on proximity once the game called for the idle fighting stance of the character all of that characters graphics would have been loaded into RAM since physically they are all next to each other on the ROM.

Boiling it all down: We don’t really need virtual memory or swap – we need intelligent disk caching.

Questions/Comments?
 
The thing that would worry me is the drastical reduced lifetime of the sd card when used for swap.
You guys are missing a critical point. You don't need to save the LRU pages back to the SD card. You can just flush it from memory and forget about it. The emulator is accessing ROM (read-only memory). The ROM code won't be modifying any data in the ROM memory so there is no need to save the flushed pages back to the SD card. If a page gets flushed from memory and then accessed again later, you just reload that page from the SD card.

The only thing you would need to worry about is if the game system that you are emulating has more RAM than the GP2X. I'm not aware of any that did however. Even the PS2 only has 32MB of RAM.

Exactly - I'm glad I'm not the only person that see's it -- now if we can just get everybody else on board.
 
Last edited by a moderator:
I assume that the biggest problem is speed. Keep in mind that this solution is only needed for emulators that'll allready use all the power from the processor.
 
Digitalrat:
We do have 2 CPUs. Or are you saying 2x200MHz isn't enough?

Hey, I read through all this and I dont have much to say that has not already been said.

I agree with the method. I'm sure NightKnight is working on somethink like this already.
 
Last edited by a moderator:
The best way to do this would of course be to do it pre-Linux, as trying to do something like this whilst in linux would be silly due to restrictions such as ram, and having no access to the mmu. Prelinux would mean full ram access and MMU control, which would be a lot faster than trying to do it in software.
 
I assume that the biggest problem is speed. Keep in mind that this solution is only needed for emulators that'll allready use all the power from the processor.
Speed is a concern but I don't think that it will be prohibitively slow. At worst you'll just see occasional one-frame hitches as pages are streamed in on demand. For games that you have the source code to, it is smart to provide a way for the game to provide hints to the loader by adding prefetch event triggers to your engine.

Let's say I'm running down a street and there's a big boss enemy just around the corner. It would be smart to drop a trigger somewhere on the street that causes the loader to prefetch the boss' textures, animations, and sound effects. That way you don't get a hitch when the player turns the corner.

Even DVD seek/read latencies can be overcome by using prefetch triggers. With EMU's it's harder since the only way to generate prefetching hints is by using the "speculative" thread idea that I outlined above.

EDIT: for spelling
 
Last edited by a moderator:
The best way to do this would of course be to do it pre-Linux, as trying to do something like this whilst in linux would be silly due to restrictions such as ram, and having no access to the mmu. Prelinux would mean full ram access and MMU control, which would be a lot faster than trying to do it in software.
Typically you wouldn't want to use the MMU since the emulator already manages the memory space of the emulated device. The EMU itself would have to manage detecting page misses and such. You could make this work under Linux. You would just malloc the memory needed for the RAM space of the emulated hardware, and malloc a large block of memory for streaming ROM pages into and out of as needed.

You're right though that the Linux kernel does restrict the amount of memory that you can use as well as eats CPU resources.
 
Last edited by a moderator:
Without getting into the whole MMU and such, you can sometimes get away with a lot purely in software; I've had some success with ROM paging, depending on the nature of the emulated code. (ie: Some programs will be jumping all over the place, making it not really feasible to do paging, while others will be very linear and limited to certain areas, so paging can work pretty well.) ie: Neo Geo for instance tends to be limited to certain chunks.. certain artworks will be used, and then it won't need the rest; likewise, the code tends to be pretty dense, especially the MVS CD versions.. but I've never looked into an MVS pager so it might just suck :)

(FWIW, paging for an ST emu sucks ass, since ST proggies tend to be all over the 1MB ram space; I was working on an ST emu that fit into 1MB of RAM, which had to include most of the OS plus the applicatoin space.. rough, and it stunk ass in the end :)

jeff
 
Back
Top