private static void ReplacementPolicyUpdate(Event aEvent) { // increase the lru value of all tags held in the MMU for (int j = 0; j < MAX_TAG_VALUE; j++) { if (memoryManagementUnit[j].citizen) { memoryManagementUnit[j].lruValue++; } } // set the lru value of the tag we just hit to 0 memoryManagementUnit[aEvent._trDataTags].lruValue = 0; }
//Prints event info private static void PrintMsg(string state, Event aEvent) { Console.WriteLine(state + (aEvent._eventId + 1) + " at tClk " + tCurrentClock + " with plans to end at " + aEvent._tClockEnd); }
// Parses the traffic csv file, and initializes all of the // device events. private static void ParseTrafficFile(string filePath) { TextFieldParser parser = new TextFieldParser(filePath); parser.SetDelimiters(","); // Skip over header line. parser.ReadLine(); int i = 0; while (!parser.EndOfData) { string[] fields = parser.ReadFields(); // allocate the memory for the event and add it to the list. Event eventToAdd = new Event( ulong.Parse(fields[(int)FieldTypes.TIME]), fields[(int)FieldTypes.OPERATION], int.Parse(fields[(int)FieldTypes.DEVICE]), int.Parse(fields[(int)FieldTypes.TS]), int.Parse(fields[(int)FieldTypes.TR_DATA_TAG]), i ); _listOfEvents.Add(eventToAdd); i++; } numEvents = i; }
// ************** GET DATA FROM DATA CENTER *************** // Starts a sat downlink event to grab a tag from the data center. private static ulong GetFromDataCenter(Event aEvent) { ulong additionalLatency = 0; Event pullDown = new Event( tCurrentClock, "REQUEST", SATELLITE_UPLINK_ID, // because we add 4 to requests in the main loop aEvent._transactionSize, aEvent._trDataTags, ++numEvents ); _listOfEvents.Add(pullDown); devices[SATELLITE_DOWNLINK_ID].linkOccupiedBy = numEvents; additionalLatency = devices[SATELLITE_DOWNLINK_ID].CalculateLatency(aEvent._transactionSize); pullDown._tClockEnd = tCurrentClock + additionalLatency; PrintMsg("Pulling from Datacenter ", pullDown); return additionalLatency; }
// ****************** EVICT A TAG FROM MEMORY ***************** private static ulong Evict(int ts) { ulong additionalLatency; // memory is full, satellite uplink is available, start evicting int tagToEvict = ExecuteReplacementPolicy(ts); // start an event to transfer the memory out to the data center // using the satellite hub Event eviction = new Event( tCurrentClock, "SEND", SATELLITE_UPLINK_ID, memoryManagementUnit[tagToEvict].size, tagToEvict, ++numEvents ); // once the eviction has started, the block is no longer valid. // but we must wait until the eviction event is finished before memoryManagementUnit[tagToEvict].citizen = false; memoryManagementUnit[tagToEvict].tClkFinish = 0; _listOfEvents.Add(eviction); devices[SATELLITE_UPLINK_ID].linkOccupiedBy = numEvents; additionalLatency = devices[SATELLITE_UPLINK_ID].CalculateLatency(memoryManagementUnit[tagToEvict].size); eviction._tClockEnd = tCurrentClock + additionalLatency; PrintMsg("Eviction ", eviction); return additionalLatency; }
// ************* MEMORYALLOCATE ************** // Check if we can allocate memory for the queued transaction // Returns true if we can, otherwise returns false // Takes in additional latency by reference and will // add any additional latencies the allocation results in // (for example, if we evict memory to make room, the latency of the // of the eviction process will be added to additionalLatency) // private static bool AllocateMemory(Event aEvent, int maxTotalMemory, ref ulong additionalLatency) { //additionalLatency = 0; bool success = false; // if the event is a send if (aEvent._operation == "SEND") { // check if we have available memory if (maxTotalMemory - allocatedMemory >= aEvent._transactionSize) { allocatedMemory += aEvent._transactionSize; success = true; } else if (devices[SATELLITE_UPLINK_ID].linkOccupiedBy == -1) { // No room, but the sat uplink is available additionalLatency += Evict(aEvent._transactionSize); success = true; } // memory is full, satellite uplink is unavailable, stall device //PrintMsg("Stall SEND device, Mem full, sat busy ", aEvent); } else { // if the event is a request // check if the tag is in our memory if(memoryManagementUnit[aEvent._trDataTags].citizen) { // it is, we are successful if (memoryManagementUnit[aEvent._trDataTags].tClkFinish <= tCurrentClock) { success = true; } } else if (devices[SATELLITE_DOWNLINK_ID].linkOccupiedBy == -1 && !memoryManagementUnit[aEvent._trDataTags].incoming) { // If the data is not coming from a device later, we can get it from the data center // as well as if we have memory to recieve it if(maxTotalMemory - allocatedMemory >= aEvent._transactionSize) { // wonderful, we have space, we can first get it from the satellite. additionalLatency += GetFromDataCenter(aEvent); success = true; } else if (devices[SATELLITE_UPLINK_ID].linkOccupiedBy == -1) { // ungh... this is where things get complicat // We need to evict things to make room for what we want from the data center. // The uplink is free, so we can go ahead and do that, allowing us to request // the data from the satellite. // Having this in here makes me think there is still a logically simplier way. additionalLatency += Evict(aEvent._transactionSize); additionalLatency += GetFromDataCenter(aEvent); success = true; } // PrintMsg("Stall REQUEST device, Mem full, sat busy ", aEvent); // Both satellite links are busy. // Memory is full. // Stall initiating transfer // success is still false from initialzation. } } return success; }