- Cached Program search is faster/smarter thanks to an idea Jake had to search recently used blocks first.
- Fixed a problem with block searching.
- Minor changes.

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1203 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
cottonvibes 2009-05-16 08:43:56 +00:00
parent 9d38252d0e
commit 2c3043862d
3 changed files with 47 additions and 35 deletions

View File

@ -53,7 +53,7 @@ microVUt(void) mVUinit(VURegs* vuRegsPtr) {
mVUreset<vuIndex>();
}
// Will Optimize later
// Resets Rec Data
microVUt(void) mVUreset() {
microVU* mVU = mVUx;
@ -86,7 +86,6 @@ microVUt(void) mVUreset() {
}*/
// Program Variables
mVU->prog.finished = 1;
mVU->prog.cleared = 1;
mVU->prog.cur = -1;
mVU->prog.total = -1;
@ -125,9 +124,11 @@ microVUt(void) mVUclose() {
microVUt(void) mVUclear(u32 addr, u32 size) {
microVU* mVU = mVUx;
if (!mVU->prog.cleared) {
memset(&mVU->prog.lpState, 0, sizeof(mVU->prog.lpState));
mVU->prog.cleared = 1; // Next execution searches/creates a new microprogram
}
}
//------------------------------------------------------------------
// Micro VU - Private Functions
@ -198,30 +199,36 @@ microVUt(int) mVUfindLeastUsedProg() {
microVUt(void) __mVUvsyncUpdate() {
microVU* mVU = mVUx;
if (mVU->prog.total < mVU->prog.max) return;
for (int i = 0; i <= mVU->prog.total; i++) {
if( mVU->prog.prog[i].last_used != 0 )
{
if( mVU->prog.prog[i].last_used >= 3 )
{
// program has been used recently. Give it's program execution counter a
// 'weighted' bonus signifying it's importance:
if( mVU->prog.prog[i].used < 0x4fffffff )
mVU->prog.prog[i].used += 0x200;
if (mVU->prog.prog[i].last_used != 0) {
if (mVU->prog.prog[i].last_used >= 3) {
if (mVU->prog.prog[i].used < 0x4fffffff) // program has been used recently. Give it a
mVU->prog.prog[i].used += 0x200; // 'weighted' bonus signifying it's importance
}
mVU->prog.prog[i].last_used--;
}
else
mVU->prog.prog[i].used /= 2; // penalize unused programs.
else mVU->prog.prog[i].used /= 2; // penalize unused programs.
}
}
void mVUvsyncUpdate()
{
__mVUvsyncUpdate<0>();
__mVUvsyncUpdate<1>();
microVUt(int) mVUcmpProg(int progIndex, bool progUsed, bool needOverflowCheck) {
microVU* mVU = mVUx;
if (progUsed) {
if (!memcmp_mmx(mVU->prog.prog[progIndex].data, mVU->regs->Micro, mVU->microSize)) {
mVU->prog.cur = progIndex;
mVU->prog.cleared = 0;
mVU->prog.prog[progIndex].last_used = 3;
if (!needOverflowCheck || mVU->prog.prog[progIndex].used < 0x7fffffff) {
mVU->prog.prog[progIndex].used++; // increment 'used' (avoiding overflows if necessary)
}
return 1;
}
}
return 0;
}
// Searches for Cached Micro Program and sets prog.cur to it (returns 1 if program found, else returns 0)
@ -230,15 +237,12 @@ microVUt(int) mVUsearchProg() {
if (mVU->prog.cleared) { // If cleared, we need to search for new program
for (int i = 0; i <= mVU->prog.total; i++) {
if (!memcmp_mmx(mVU->prog.prog[i].data, mVU->regs->Micro, mVU->microSize)) {
mVU->prog.cur = i;
mVU->prog.cleared = 0;
if( mVU->prog.prog[i].used < 0x7fffffff ) // avoid overflows on well-used programs
mVU->prog.prog[i].used++;
mVU->prog.prog[i].last_used = 3; // add me to the mVU structs
return 1;
if (mVUcmpProg<vuIndex>(i, !!mVU->prog.prog[i].used, 1))
return 1; // Check Recently Used Programs
}
for (int i = 0; i <= mVU->prog.total; i++) {
if (mVUcmpProg<vuIndex>(i, !mVU->prog.prog[i].used, 0))
return 1; // Check Older Programs
}
mVU->prog.cur = mVUfindLeastUsedProg<vuIndex>(); // If cleared and program not found, make a new program instance
mVU->prog.cleared = 0;
@ -297,4 +301,9 @@ void runVUrec(u32 startPC, u32 cycles, const int vuIndex) {
else startVU1(startPC, cycles);
}
void mVUvsyncUpdate() {
__mVUvsyncUpdate<0>();
__mVUvsyncUpdate<1>();
}
#endif // PCSX2_MICROVU

View File

@ -27,7 +27,7 @@
#include "microVU_Alloc.h"
#include "microVU_Misc.h"
#define mMaxBlocks 32 // Max Blocks With Different Pipeline States (For n = 1, 2, 4, 8, 16, etc...)
#define mMaxBlocks 32 // Max Blocks With Different Pipeline States
class microBlockManager {
private:
static const int MaxBlocks = mMaxBlocks - 1;
@ -42,7 +42,7 @@ public:
microBlock* thisBlock = search(&pBlock->pState);
if (!thisBlock) {
listSize++;
if (listSize > MaxBlocks) { Console::Error("microVU Warning: Block List Overflow"); listSize &= MaxBlocks; }
if (listSize > MaxBlocks) { Console::Error("microVU Warning: Block List Overflow"); listSize = 0; }
memcpy_fast(&blockList[listSize], pBlock, sizeof(microBlock));
thisBlock = &blockList[listSize];
}
@ -57,8 +57,10 @@ public:
}
else { // Can do Simple Search (Only Matches the Important Pipeline Stuff)
for (int i = 0; i <= listSize; i++) {
if ((blockList[i].pState.q == pState->q) && (blockList[i].pState.p == pState->p)
&& (blockList[i].pState.flags == pState->flags)) { return &blockList[i]; }
if ((blockList[i].pState.q == pState->q)
&& (blockList[i].pState.p == pState->p)
&& (blockList[i].pState.flags == pState->flags)
&& !(blockList[i].pState.needExactMatch & 0xf0f)) { return &blockList[i]; }
}
}
return NULL;
@ -69,8 +71,9 @@ template<u32 progSize> // progSize = VU program memory size / 4
struct microProgram {
u32 data[progSize];
u32 used; // Number of times its been used
u32 last_used; // counters # of frames since last use (starts at 3 and counts backwards to 0 for each 30fps vsync)
u32 last_used; // Counters # of frames since last use (starts at 3 and counts backwards to 0 for each 30fps vSync)
u32 sFlagHack; // Optimize out Status Flag Updates if Program doesn't use Status Flags
s32 range[2]; // The range of microMemory that has already been recompiled for the current program
u8* x86ptr; // Pointer to program's recompilation code
u8* x86start; // Start of program's rec-cache
u8* x86end; // Limit of program's rec-cache
@ -85,8 +88,8 @@ struct microProgManager {
static const int max = mMaxProg - 1;
int cur; // Index to Current MicroProgram thats running (-1 = uncached)
int total; // Total Number of valid MicroPrograms minus 1
int isSame; // Current cached microProgram is Exact Same program as mVU->regs->Micro
int cleared; // Micro Program is Indeterminate so must be searched for (and if no matches are found then recompile a new one)
int finished; // Completed MicroProgram by E-bit Termination
microRegInfo lpState; // Pipeline state from where program left off (useful for continuing execution)
};

View File

@ -108,7 +108,7 @@ microVUt(void) mVUdispatcherB() {
if (isMMX(1)) EMMS();
RET();
mVUcacheCheck(x86Ptr, mVU->cache, 512);
mVUcacheCheck(x86Ptr, mVU->cache, 0x1000);
}
//------------------------------------------------------------------