#include "precomp.h" // from casting your gonna vomit const int LineSize = 64; const int Offset = (int)log2((double)LineSize); int rngarray[1000]; int rngcounter; struct CacheAddress { uint tag; uint offset; uint valid; uint dirty; uint linenummer; uint rest; int* nooffset; }; struct CacheLine { CacheAddress address; union dataline{ int di[LineSize / 4]; }data; }; //L1 const uint L1CacheSize = 32; const uint L1Associative = 8; const uint L1CacheRows = L1CacheSize * 1024 / ((LineSize)*L1Associative); const uint L1Index = (uint)ceil(log2((double)L1CacheRows)); //L2 const uint L2CacheSize = 256; const uint L2Associative = 8; const uint L2CacheRows = L1CacheSize * 1024 / ((LineSize)*L1Associative); const uint L2Index = (uint)ceil(log2((double)L1CacheRows)); //L3 const uint L3CacheSize = (2 * 1024); //2048 KB = 2 MB const uint L3Associative = 16; const uint L3CacheRows = L1CacheSize * 1024 / ((LineSize)*L1Associative); const uint L3Index = (uint)ceil(log2((double)L1CacheRows)); CacheLine L1[L1CacheRows][L1Associative]; CacheLine L2[L2CacheSize][L2Associative]; CacheLine L3[L3CacheSize][L3Associative]; void CleanCacheL1(CacheLine cachearray[L1CacheRows][L1Associative]) { for (uint i = 0; i < L1CacheRows; i++) { for (uint j = 0; j < L1Associative; j++) { cachearray[i][j].address.valid = 0; cachearray[i][j].address.dirty = 0; } } } void CleanCacheL2(CacheLine cachearray[L2CacheRows][L2Associative]) { for (uint i = 0; i < L2CacheRows; i++) { for (uint j = 0; j < L2Associative; j++) { cachearray[i][j].address.valid = 0; cachearray[i][j].address.dirty = 0; } } } void CleanCacheL3(CacheLine cachearray[L3CacheRows][L3Associative]) { for (uint i = 0; i < L3CacheRows; i++) { for (uint j = 0; j < L3Associative; j++) { cachearray[i][j].address.valid = 0; cachearray[i][j].address.dirty = 0; } } } void InitializeCache() { srand(1); for (int i = 0; i < 1000; i++) { rngarray[i] = rand() % 8; } rngcounter = 0; CleanCacheL1(L1); CleanCacheL2(L2); CleanCacheL3(L3); } CacheAddress ConvertToCacheAddress(int* address) { uint castaddress = (uint)address; CacheAddress cacheline; cacheline.tag = castaddress >> (Offset + L1Index); //tag with valid and dirty cacheline.valid = castaddress >> (31); cacheline.dirty = castaddress << 1 >> (31); cacheline.offset = castaddress << (32 - Offset) >> (32 - Offset); cacheline.linenummer = castaddress << (32 - Offset - L1Index) >> (32 - L1Index); cacheline.rest = castaddress << 2 >> (Offset + L1Index + 2); cacheline.nooffset = (int*)(castaddress >> Offset << Offset); return cacheline; /*uint offsetaddress = (bla << (32 - Offset) >> (32 - Offset)); uint addressnooffset = (bla >> Offset << Offset); int* newaddress = (int*)(offsetaddress | addressnooffset);*/ } //CacheLine Read(CacheLine cacheline) //{ // //} // //CacheLine Write(CacheLine cacheline) //{ // //} int READ( int* address ) { #pragma region L1 CacheAddress workaddress = ConvertToCacheAddress(address); int value = 0; for (uint i = 0; i < L1Associative; i++) //finding address in cache to update { if (L1[workaddress.linenummer][i].address.valid) { if (L1[workaddress.linenummer][i].address.rest == workaddress.rest) { // HIT! value = L1[workaddress.linenummer][i].data.di[workaddress.offset >> 2]; return value; } } } #pragma endregion //No Hit #pragma region L2 value = 0; for (uint i = 0; i < L2Associative; i++) //finding address in cache to update { if (L2[workaddress.linenummer][i].address.valid) { if (L2[workaddress.linenummer][i].address.rest == workaddress.rest) { // HIT! value = L2[workaddress.linenummer][i].data.di[workaddress.offset >> 2]; return value; } } } #pragma endregion //still no Hit #pragma region L3 value = 0; for (uint i = 0; i < L3Associative; i++) //finding address in cache to update { if (L3[workaddress.linenummer][i].address.valid) { if (L3[workaddress.linenummer][i].address.rest == workaddress.rest) { // HIT! value = L3[workaddress.linenummer][i].data.di[workaddress.offset >> 2]; return value; } } } #pragma endregion // we give up #pragma region RAM value = ReadFromRAM(address); WRITE(address, value); // TODO : write the writepart here instead of first getting the value. //CacheLine cacheline = Read((CacheLine)) // prevent ReadFromRAM using caching return value;//ReadFromRAM( address ); #pragma endregion } uint EvictionPolicy() //fuuuuuuu randoms { uint value = rngarray[rngcounter]; rngcounter = (rngcounter + 1) % 1000; /* uint value = 0; // rand() % 8; //cout << value << " "; */ return value; } void WRITE(int* address, int value) { CacheAddress workaddress = ConvertToCacheAddress(address); for (uint i = 0; i < L1Associative; i++) //finding address in cache to update { if (L1[workaddress.linenummer][i].address.valid) { if (L1[workaddress.linenummer][i].address.rest == workaddress.rest) { L1[workaddress.linenummer][i].data.di[workaddress.offset >> 2] = value; // TODO : er bevind zich op het moment 64 bytes aan data hierin. L1[workaddress.linenummer][i].address.dirty = 1; // address.tag zou hier ook moeten veranderen. return; } } } for (uint i = 0; i < L1Associative; i++) // finding empty spot to store value { if (!L1[workaddress.linenummer][i].address.valid) { L1[workaddress.linenummer][i].address.tag = workaddress.tag; L1[workaddress.linenummer][i].address.rest = workaddress.rest; L1[workaddress.linenummer][i].address.offset = workaddress.offset; L1[workaddress.linenummer][i].address.linenummer = workaddress.linenummer; L1[workaddress.linenummer][i].address.nooffset = workaddress.nooffset; int* tempaddress = workaddress.nooffset; for (uint j = 0; j < LineSize / 4; j++) { L1[workaddress.linenummer][i].data.di[j] = ReadFromRAM(tempaddress); tempaddress++; } L1[workaddress.linenummer][i].data.di[workaddress.offset >> 2] = value; L1[workaddress.linenummer][i].address.dirty = 1; L1[workaddress.linenummer][i].address.valid = 1; return; } } // TODO Eviction uint slot = EvictionPolicy(); //copy to RAM if dirty if (L1[workaddress.linenummer][slot].address.dirty) { int* tempaddress = L1[workaddress.linenummer][slot].address.nooffset; for (uint i = 0; i < LineSize / 4; i++) { WriteToRAM(tempaddress, L1[workaddress.linenummer][slot].data.di[i]); tempaddress++; } L1[workaddress.linenummer][slot].address.dirty = 0; L1[workaddress.linenummer][slot].address.valid = 0; } WRITE(address, value); //replace data with data from RAM // prevent WriteToRAM using caching //WriteToRAM( address, value ); } /* bitshifting works uint bla = (uint)address; uint offsetaddress = (bla << (32 - Offset) >> (32 - Offset)); uint addressnooffset = (bla >> Offset << Offset); int* newaddress = (int*)(offsetaddress | addressnooffset); //cout << newaddress << "-" << address << endl; */ /* // Eviction backup uint slot = EvictionPolicy(); int* tempaddress = L1[workaddress.linenummer][slot].address.nooffset; if (L1[workaddress.linenummer][slot].address.dirty) { for (uint i = 0; i < (LineSize / 4); i++) { WriteToRAM(tempaddress, L1[workaddress.linenummer][slot].data.di[i]); tempaddress++; } L1[workaddress.linenummer][slot].address.dirty = 0; L1[workaddress.linenummer][slot].address.valid = 0; } L1[workaddress.linenummer][slot].address.tag = workaddress.tag; L1[workaddress.linenummer][slot].address.rest = workaddress.rest; L1[workaddress.linenummer][slot].address.offset = workaddress.offset; L1[workaddress.linenummer][slot].address.linenummer = workaddress.linenummer; L1[workaddress.linenummer][slot].address.nooffset = workaddress.nooffset; tempaddress = workaddress.nooffset; for (uint i = 0; i < (LineSize / 4); i++) { L1[workaddress.linenummer][slot].data.di[i] = ReadFromRAM(tempaddress); tempaddress++; } L1[workaddress.linenummer][slot].data.di[workaddress.offset >> 2] = value; L1[workaddress.linenummer][slot].address.valid = 1; L1[workaddress.linenummer][slot].address.dirty = 1; */