newVif: created a custom memcmp for the vif dynarec block finder... its faster than memcmp, but not sure if it will be a noticeable speedup.

Should work in gcc Linux builds, but if not uncomment the memcmp() part in newVif_HashBucket.h's "find()"...


git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2367 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
cottonvibes 2009-12-20 04:25:16 +00:00
parent c86fc2c9b9
commit 7b2c66e549
4 changed files with 50 additions and 22 deletions

View File

@ -48,19 +48,30 @@ static __aligned16 u32 nVifMask[3][4][4] = {0}; // [MaskNumber][CycleNumber][
#define xmmRow xmm6
#define xmmTemp xmm7
struct nVifBlock { // Ordered for Hashing
u8 num; // Num Field
u8 upkType; // Unpack Type [usn*1:mask*1:upk*4]
u8 mode; // Mode Field
u8 scl; // Start Cycle
u8 cl; // CL Field
u8 wl; // WL Field
u32 mask; // Mask Field
u8* startPtr; // Start Ptr of RecGen Code
};
#ifdef _MSC_VER
# pragma pack(1)
# pragma warning(disable:4996) // 'function': was declared deprecated
#endif
struct __aligned16 nVifBlock { // Ordered for Hashing
u8 num; // [00] Num Field
u8 upkType; // [01] Unpack Type [usn*1:mask*1:upk*4]
u8 mode; // [02] Mode Field
u8 scl; // [03] Start Cycle
u8 cl; // [04] CL Field
u8 wl; // [05] WL Field
u32 mask; // [06] Mask Field
u8 padding[6];// [10] through [15]
uptr startPtr; // [16] Start Ptr of RecGen Code
u8 end[12]; // [20] through [31]
} __packed; // 32 bytes
#ifdef _MSC_VER
# pragma pack()
#endif
#define _hSize 0x4000 // [usn*1:mask*1:upk*4:num*8] hash...
#define _cmpS (sizeof(nVifBlock) - sizeof(uptr))
#define _cmpS (sizeof(nVifBlock) - (16+6))
#define _tParams nVifBlock, _hSize, _cmpS
struct nVifStruct {
u32 idx; // VIF0 or VIF1

View File

@ -30,6 +30,7 @@ void dVifInit(int idx) {
nVif[idx].vifBlocks = new HashBucket<_tParams>();
nVif[idx].recPtr = nVif[idx].vifCache->getBlock();
nVif[idx].recEnd = &nVif[idx].recPtr[nVif[idx].vifCache->getSize()-(_1mb/4)]; // .25mb Safe Zone
emitCustomCompare();
}
_f void dVifRecLimit(int idx) {
@ -75,7 +76,7 @@ void dVifRecompile(nVifStruct& v, nVifBlock* vB) {
v.vifBlock = vB;
xSetPtr(v.recPtr);
xAlignPtr(16);
vB->startPtr = xGetPtr();
vB->startPtr = (uptr)xGetPtr();
dVifSetMasks(v, doMask, doMode, cycleSize);
while (vifRegs->num) {
@ -107,7 +108,7 @@ void dVifRecompile(nVifStruct& v, nVifBlock* vB) {
vifRegs->num = backupNum;
}
static nVifBlock _vBlock = {0};
static __aligned16 nVifBlock _vBlock = {0};
_f u8* dVifsetVUptr(nVifStruct& v, int offset) {
u8* ptr = (u8*)(v.VU->Mem + (offset & v.vuMemLimit));
@ -148,10 +149,8 @@ void dVifUnpack(int idx, u8 *data, u32 size) {
}
static int recBlockNum = 0;
DevCon.WriteLn("nVif: Recompiled Block! [%d]", recBlockNum++);
nVifBlock* vB = new nVifBlock();
memcpy(vB, &_vBlock, sizeof(nVifBlock));
dVifRecompile(v, vB);
v.vifBlocks->add(vB);
dVifRecompile(v, &_vBlock);
v.vifBlocks->add(&_vBlock);
dVifRecLimit(idx);
dVifUnpack(idx, data, size);
}

View File

@ -15,9 +15,11 @@
#pragma once
extern __pagealigned u8 nVifMemCmp[__pagesize];
// HashBucket is a container which uses a built-in hash function
// to perform quick searches.
// T is a struct data type.
// T is a struct data type (note: size must be in multiples of 16 bytes!)
// hSize determines the number of buckets HashBucket will use for sorting.
// cmpSize is the size of data to consider 2 structs equal (see find())
// The hash function is determined by taking the first bytes of data and
@ -46,7 +48,8 @@ public:
int s = mSize[o];
T* c = mChain[o];
for (int i = 0; i < s; i++) {
if (!memcmp(&c[i], dataPtr, cmpSize)) return &c[i];
//if (!memcmp(&c[i], dataPtr, cmpSize)) return &c[i];
if ((((nVifCall)((void*)nVifMemCmp))(&c[i], dataPtr))==0xf) return &c[i];
}
return NULL;
}
@ -55,17 +58,17 @@ public:
int o = d % hSize;
int s = mSize[o]++;
T* c = mChain[o];
T* n = new T[s+1];
T* n = (T*)_aligned_malloc(sizeof(T)*(s+1), 16);
if (s) {
memcpy(n, c, sizeof(T) * s);
delete[] c;
safe_aligned_free(c);
}
memcpy(&n[s], dataPtr, sizeof(T));
mChain[o] = n;
}
void clear() {
for (int i = 0; i < hSize; i++) {
safe_delete_array(mChain[i]);
safe_aligned_free(mChain[i]);
mSize[i] = 0;
}
}

View File

@ -271,3 +271,18 @@ void writeBackRow(nVifStruct& v) {
DevCon.WriteLn("nVif: writing back row reg! [doMode = 2]");
// ToDo: Do we need to write back to vifregs.rX too!? :/
}
static __pagealigned u8 nVifMemCmp[__pagesize];
void emitCustomCompare() {
HostSys::MemProtectStatic(nVifMemCmp, Protect_ReadWrite, false);
memset_8<0xcc,__pagesize>(nVifMemCmp);
xSetPtr(nVifMemCmp);
xMOVAPS (xmm0, ptr32[ecx]);
xPCMP.EQD(xmm0, ptr32[edx]);
xMOVMSKPS(eax, xmm0);
xRET();
HostSys::MemProtectStatic(nVifMemCmp, Protect_ReadOnly, true);
}