microVU: Improved microProgram management/searching.

Instead of just having live/dead programs, we now have young/old/dead programs.


git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1578 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
cottonvibes 2009-07-28 01:36:37 +00:00
parent 3935927a99
commit 2bcf704ff3
2 changed files with 25 additions and 12 deletions

View File

@ -134,6 +134,7 @@ microVUf(void) mVUclearProg(int progIndex) {
microVU* mVU = mVUx; microVU* mVU = mVUx;
mVUprogI.used = 0; mVUprogI.used = 0;
mVUprogI.isDead = 1; mVUprogI.isDead = 1;
mVUprogI.isOld = 1;
mVUprogI.frame = mVU->prog.curFrame; mVUprogI.frame = mVU->prog.curFrame;
for (int j = 0; j <= mVUprogI.ranges.max; j++) { for (int j = 0; j <= mVUprogI.ranges.max; j++) {
mVUprogI.ranges.range[j][0] = -1; // Set range to mVUprogI.ranges.range[j][0] = -1; // Set range to
@ -173,8 +174,9 @@ microVUf(int) mVUfindLeastUsedProg() {
if (mVU->prog.prog[i].isDead) { if (mVU->prog.prog[i].isDead) {
mVU->prog.total++; mVU->prog.total++;
mVUcacheProg<vuIndex>(i); // Cache Micro Program mVUcacheProg<vuIndex>(i); // Cache Micro Program
mVU->prog.prog[i].isDead = 0; mVU->prog.prog[i].isDead = 0;
mVU->prog.prog[i].used = 1; mVU->prog.prog[i].isOld = 0;
mVU->prog.prog[i].used = 1;
mVUsortProg(mVU, i); mVUsortProg(mVU, i);
Console::Notice("microVU%d: Cached MicroPrograms = [%03d] [%03d]", params vuIndex, i+1, mVU->prog.total+1); Console::Notice("microVU%d: Cached MicroPrograms = [%03d] [%03d]", params vuIndex, i+1, mVU->prog.total+1);
return i; return i;
@ -189,14 +191,15 @@ microVUf(int) mVUfindLeastUsedProg() {
} }
mVU->prog.total -= ((mVU->prog.max+1)/4)-1; mVU->prog.total -= ((mVU->prog.max+1)/4)-1;
mVUcacheProg<vuIndex>(pIdx); // Cache Micro Program mVUcacheProg<vuIndex>(pIdx); // Cache Micro Program
mVU->prog.prog[pIdx].isDead = 0; mVU->prog.prog[pIdx].isDead = 0;
mVU->prog.prog[pIdx].used = 1; mVU->prog.prog[pIdx].isOld = 0;
mVU->prog.prog[pIdx].used = 1;
mVUsortProg(mVU, pIdx); mVUsortProg(mVU, pIdx);
Console::Notice("microVU%d: Cached MicroPrograms = [%03d] [%03d]", params vuIndex, pIdx+1, mVU->prog.total+1); Console::Notice("microVU%d: Cached MicroPrograms = [%03d] [%03d]", params vuIndex, pIdx+1, mVU->prog.total+1);
return pIdx; return pIdx;
} }
// Finds and Kills Programs if they haven't been used in a while. // Finds and Ages/Kills Programs if they haven't been used in a while.
microVUt(void) mVUvsyncUpdate(mV) { microVUt(void) mVUvsyncUpdate(mV) {
for (int i = 0; i <= mVU->prog.max; i++) { for (int i = 0; i <= mVU->prog.max; i++) {
if (mVU->prog.prog[i].isDead) continue; if (mVU->prog.prog[i].isDead) continue;
@ -204,12 +207,16 @@ microVUt(void) mVUvsyncUpdate(mV) {
mVU->prog.prog[i].used = 0; mVU->prog.prog[i].used = 0;
mVU->prog.prog[i].frame = mVU->prog.curFrame; mVU->prog.prog[i].frame = mVU->prog.curFrame;
} }
if((mVU->prog.curFrame - mVU->prog.prog[i].frame) >= (60 * 7)) { if((mVU->prog.curFrame - mVU->prog.prog[i].frame) >= (360 * 10)) {
mVU->prog.total--; mVU->prog.total--;
if (!mVU->index) mVUclearProg<0>(i); if (!mVU->index) mVUclearProg<0>(i);
else mVUclearProg<1>(i); else mVUclearProg<1>(i);
DevCon::Status("microVU%d: Killing Dead Program [%03d]", params mVU->index, i+1); DevCon::Status("microVU%d: Killing Dead Program [%03d]", params mVU->index, i+1);
} }
else if (!mVU->prog.prog[i].isOld && ((mVU->prog.curFrame - mVU->prog.prog[i].frame) >= (30 * 1))) {
mVU->prog.prog[i].isOld = 1;
//DevCon::Status("microVU%d: Aging Old Program [%03d]", params mVU->index, i+1);
}
} }
mVU->prog.curFrame++; mVU->prog.curFrame++;
} }
@ -227,15 +234,16 @@ microVUf(bool) mVUcmpPartial(int progIndex) {
} }
// Compare Cached microProgram to mVU->regs->Micro // Compare Cached microProgram to mVU->regs->Micro
microVUf(bool) mVUcmpProg(int progIndex, const bool cmpWholeProg) { microVUf(bool) mVUcmpProg(int progIndex, const bool checkOld, const bool cmpWholeProg) {
microVU* mVU = mVUx; microVU* mVU = mVUx;
if (!mVUprogI.isDead) { if (!mVUprogI.isDead && (checkOld == mVUprogI.isOld)) {
if ((cmpWholeProg && !memcmp_mmx((u8*)mVUprogI.data, mVU->regs->Micro, mVU->microMemSize)) if ((cmpWholeProg && !memcmp_mmx((u8*)mVUprogI.data, mVU->regs->Micro, mVU->microMemSize))
|| (!cmpWholeProg && mVUcmpPartial<vuIndex>(progIndex))) { || (!cmpWholeProg && mVUcmpPartial<vuIndex>(progIndex))) {
mVU->prog.cur = progIndex; mVU->prog.cur = progIndex;
mVU->prog.cleared = 0; mVU->prog.cleared = 0;
mVU->prog.isSame = cmpWholeProg ? 1 : -1; mVU->prog.isSame = cmpWholeProg ? 1 : -1;
mVU->prog.prog[progIndex].used = 1; mVU->prog.prog[progIndex].used = 1;
mVU->prog.prog[progIndex].isOld = 0;
return 1; return 1;
} }
} }
@ -247,8 +255,12 @@ microVUf(int) mVUsearchProg() {
microVU* mVU = mVUx; microVU* mVU = mVUx;
if (mVU->prog.cleared) { // If cleared, we need to search for new program if (mVU->prog.cleared) { // If cleared, we need to search for new program
for (int i = mVU->prog.max; i >= 0; i--) { for (int i = mVU->prog.max; i >= 0; i--) {
if (mVUcmpProg<vuIndex>(mVU->prog.progList[i], 0)) if (mVUcmpProg<vuIndex>(mVU->prog.progList[i], 0, 0))
return 1; return 1; // Check Young Programs
}
for (int i = mVU->prog.max; i >= 0; i--) {
if (mVUcmpProg<vuIndex>(mVU->prog.progList[i], 1, 0))
return 1; // Check Old Programs
} }
mVU->prog.cur = mVUfindLeastUsedProg<vuIndex>(); // If cleared and program not found, make a new program instance mVU->prog.cur = mVUfindLeastUsedProg<vuIndex>(); // If cleared and program not found, make a new program instance
mVU->prog.cleared = 0; mVU->prog.cleared = 0;

View File

@ -110,7 +110,8 @@ struct microProgram {
microRange ranges; // The ranges of the microProgram that have already been recompiled microRange ranges; // The ranges of the microProgram that have already been recompiled
u32 frame; // Frame # the program was last used on u32 frame; // Frame # the program was last used on
u32 used; // Program was used this frame? u32 used; // Program was used this frame?
bool isDead; // Program is dead? bool isDead; // Program is Dead?
bool isOld; // Program is Old? (Program hasn't been used in a while)
}; };
#define mMaxProg ((mVU->index)?400:8) // The amount of Micro Programs Recs will 'remember' (For n = 1, 2, 4, 8, 16, etc...) #define mMaxProg ((mVU->index)?400:8) // The amount of Micro Programs Recs will 'remember' (For n = 1, 2, 4, 8, 16, etc...)