x86/microVU: Add a reference list for quick block lookups

This way, we can pack 8 entries in a single cache line, instead of one.
This commit is contained in:
Connor McLaughlin 2022-10-12 22:41:12 +10:00 committed by refractionpcsx2
parent 197d4d1c81
commit ab295f0f10
1 changed files with 38 additions and 17 deletions

View File

@ -43,11 +43,18 @@ struct microBlockLink
microBlockLink* next; microBlockLink* next;
}; };
struct microBlockLinkRef
{
microBlock* pBlock;
u64 quick;
};
class microBlockManager class microBlockManager
{ {
private: private:
microBlockLink *qBlockList, *qBlockEnd; // Quick Search microBlockLink *qBlockList, *qBlockEnd; // Quick Search
microBlockLink *fBlockList, *fBlockEnd; // Full Search microBlockLink *fBlockList, *fBlockEnd; // Full Search
std::vector<microBlockLinkRef> quickLookup;
int qListI, fListI; int qListI, fListI;
public: public:
@ -55,20 +62,20 @@ public:
microBlockManager() microBlockManager()
{ {
qListI = fListI = 0; qListI = fListI = 0;
qBlockEnd = qBlockList = NULL; qBlockEnd = qBlockList = nullptr;
fBlockEnd = fBlockList = NULL; fBlockEnd = fBlockList = nullptr;
} }
~microBlockManager() { reset(); } ~microBlockManager() { reset(); }
void reset() void reset()
{ {
for (microBlockLink* linkI = qBlockList; linkI != NULL;) for (microBlockLink* linkI = qBlockList; linkI != nullptr;)
{ {
microBlockLink* freeI = linkI; microBlockLink* freeI = linkI;
safe_delete_array(linkI->block.jumpCache); safe_delete_array(linkI->block.jumpCache);
linkI = linkI->next; linkI = linkI->next;
_aligned_free(freeI); _aligned_free(freeI);
} }
for (microBlockLink* linkI = fBlockList; linkI != NULL;) for (microBlockLink* linkI = fBlockList; linkI != nullptr;)
{ {
microBlockLink* freeI = linkI; microBlockLink* freeI = linkI;
safe_delete_array(linkI->block.jumpCache); safe_delete_array(linkI->block.jumpCache);
@ -76,8 +83,9 @@ public:
_aligned_free(freeI); _aligned_free(freeI);
} }
qListI = fListI = 0; qListI = fListI = 0;
qBlockEnd = qBlockList = NULL; qBlockEnd = qBlockList = nullptr;
fBlockEnd = fBlockList = NULL; fBlockEnd = fBlockList = nullptr;
quickLookup.clear();
}; };
microBlock* add(microBlock* pBlock) microBlock* add(microBlock* pBlock)
{ {
@ -93,8 +101,8 @@ public:
microBlockLink*& blockList = fullCmp ? fBlockList : qBlockList; microBlockLink*& blockList = fullCmp ? fBlockList : qBlockList;
microBlockLink*& blockEnd = fullCmp ? fBlockEnd : qBlockEnd; microBlockLink*& blockEnd = fullCmp ? fBlockEnd : qBlockEnd;
microBlockLink* newBlock = (microBlockLink*)_aligned_malloc(sizeof(microBlockLink), SSE_ALIGN_N); microBlockLink* newBlock = (microBlockLink*)_aligned_malloc(sizeof(microBlockLink), SSE_ALIGN_N);
newBlock->block.jumpCache = NULL; newBlock->block.jumpCache = nullptr;
newBlock->next = NULL; newBlock->next = nullptr;
if (blockEnd) if (blockEnd)
{ {
@ -106,8 +114,10 @@ public:
blockEnd = blockList = newBlock; blockEnd = blockList = newBlock;
} }
memcpy(&newBlock->block, pBlock, sizeof(microBlock)); std::memcpy(&newBlock->block, pBlock, sizeof(microBlock));
thisBlock = &newBlock->block; thisBlock = &newBlock->block;
quickLookup.push_back({&newBlock->block, pBlock->pState.quick64[0]});
} }
return thisBlock; return thisBlock;
} }
@ -115,23 +125,34 @@ public:
{ {
if (pState->needExactMatch) // Needs Detailed Search (Exact Match of Pipeline State) if (pState->needExactMatch) // Needs Detailed Search (Exact Match of Pipeline State)
{ {
for (microBlockLink* linkI = fBlockList; linkI != NULL; linkI = linkI->next) microBlockLink* prevI = nullptr;
for (microBlockLink* linkI = fBlockList; linkI != nullptr; prevI = linkI, linkI = linkI->next)
{ {
if (mVUquickSearch((void*)pState, (void*)&linkI->block.pState, sizeof(microRegInfo))) if (mVUquickSearch(pState, &linkI->block.pState, sizeof(microRegInfo)))
{
if (linkI != fBlockList)
{
prevI->next = linkI->next;
linkI->next = fBlockList;
fBlockList = linkI;
}
return &linkI->block; return &linkI->block;
}
} }
} }
else // Can do Simple Search (Only Matches the Important Pipeline Stuff) else // Can do Simple Search (Only Matches the Important Pipeline Stuff)
{ {
for (microBlockLink* linkI = qBlockList; linkI != NULL; linkI = linkI->next) const u64 quick64 = pState->quick64[0];
for (const microBlockLinkRef& ref : quickLookup)
{ {
if (linkI->block.pState.quick64[0] != pState->quick64[0]) continue; if (ref.quick != quick64) continue;
if (doConstProp && (linkI->block.pState.vi15 != pState->vi15)) continue; if (doConstProp && (ref.pBlock->pState.vi15 != pState->vi15)) continue;
if (doConstProp && (linkI->block.pState.vi15v != pState->vi15v)) continue; if (doConstProp && (ref.pBlock->pState.vi15v != pState->vi15v)) continue;
return &linkI->block; return ref.pBlock;
} }
} }
return NULL; return nullptr;
} }
void printInfo(int pc, bool printQuick) void printInfo(int pc, bool printQuick)
{ {