public override void ProcessXEvent(XEvent e) { switch ((HostInterfaceEventType)e.Type) { case HostInterfaceEventType.GenerateNextIORequest: if (XEngineFactory.XEngine.Time >= SimulationStopTime) { Finished = true; } uint streamID = (uint)e.Parameters; IORequest request = _inputStreams[streamID].GetNextIORequest(this, foldAddress, ignoreUnallocatedReads); ReceivedRequestCount++; if (request.Type == IORequestType.Write) //write request in ascii traces { ReceivedWriteRequestCount++; } else //read request in ascii traces { ReceivedReadRequestCount++; } if (request.ToBeIgnored) { ignoredRequestsCount++; } else { OnIORequestArrived(streamID); } break; case HostInterfaceEventType.RequestCompletedByDRAM: IORequest targetRequest = e.Parameters as IORequest; SendEarlyResponseToHost(targetRequest); break; default: throw new Exception("Unhandled XEvent type"); } }
private void SegmentIORequestNoCache(IORequest currentRequest) { ulong lsn = currentRequest.LSN; uint reqSize = currentRequest.SizeInSubpages; uint subState = 0; uint handledSize = 0, subSize = 0; while (handledSize < reqSize) { lsn = lsn % myFTL.AddressMapper.LargestLSN; subSize = myFTL.SubpageNoPerPage - (uint)(lsn % myFTL.SubpageNoPerPage); if (handledSize + subSize >= reqSize) { subSize = reqSize - handledSize; handledSize += subSize; } ulong lpn = lsn / myFTL.SubpageNoPerPage; subState = myFTL.SetEntryState(lsn, subSize); createFlashOperationRequest(lpn, subSize, subState, currentRequest); lsn = lsn + subSize; handledSize += subSize; } if (currentRequest.InternalRequestList.Count == 0) { myHI.SendEarlyResponseToHost(currentRequest); } /*try to estimate the execution time of each flash transaction separately*/ foreach (InternalRequest ir in currentRequest.InternalRequestList) { uint queueID = ir.TargetPageAddress.ChannelID; if (queueID == uint.MaxValue) { throw new Exception("Current implementation does not support dynamic channel allocation!"); } } }
public override IORequest SaturatedMode_GetNextRequest() { if (ReceivedRequestCount == numberOfRequestsToBeSeen) { return(null); } ulong lsn = 0; switch (addressDistributionType) { case InputStreamSynthetic.DistributionType.Uniform: lsn = randomAddressGenerator1.UniformULong(addressDistributionParam1, addressDistributionParam2); break; case InputStreamSynthetic.DistributionType.Normal: double templsn = randomAddressGenerator1.Normal(addressDistributionParam1, addressDistributionParam2); lsn = (uint)templsn; if (templsn < 0) { lsn = 0; } else if (templsn > this.FTL.AddressMapper.LargestLSN) { lsn = this.FTL.AddressMapper.LargestLSN; } break; case InputStreamSynthetic.DistributionType.Fixed: lsn = addressDistributionParam1; break; case InputStreamSynthetic.DistributionType.HotCold: if (randomHotColdRatioGenerator.Uniform(0, 1) < hotTrafficRate) { lsn = addressDistributionParam1 + randomHotAddressGenerator.UniformULong(0, hotAddressRange); } else { lsn = randomAddressGenerator1.UniformULong(0, this.FTL.AddressMapper.LargestLSN - hotAddressRange); if (lsn > addressDistributionParam1) { lsn += hotAddressRange; } } break; default: throw new Exception("Unknown distribution type for address."); } uint reqSize = 0; switch (requestSizeDistributionType) { case InputStreamSynthetic.DistributionType.Uniform: double tempReqSize = randomRequestSizeGenerator.Uniform(requestSizeDistributionParam1B, requestSizeDistributionParam2B); reqSize = (uint)(Math.Ceiling(tempReqSize / (double)FTL.SubPageCapacity)); if (reqSize == 0) { reqSize = 1; } break; case InputStreamSynthetic.DistributionType.Normal: tempReqSize = randomRequestSizeGenerator.Normal(requestSizeDistributionParam1B, requestSizeDistributionParam2B); reqSize = (uint)(Math.Ceiling(tempReqSize / (double)FTL.SubPageCapacity)); if (tempReqSize < 0) { reqSize = 1; } break; case InputStreamSynthetic.DistributionType.Fixed: reqSize = (uint)(Math.Ceiling(requestSizeDistributionParam1B / (double)FTL.SubPageCapacity)); break; default: throw new Exception("Uknown distribution type for requset size."); } IORequest request = null; if (randomRequestTypeGenerator.Uniform(0, 1) < readRatio) { request = new IORequest(XEngineFactory.XEngine.Time, lsn, reqSize, IORequestType.Read); ReceivedReadRequestCount++; } else { request = new IORequest(XEngineFactory.XEngine.Time, lsn, reqSize, IORequestType.Write); ReceivedWriteRequestCount++; } ReceivedRequestCount++; if (ReceivedRequestCount == numberOfRequestsToBeSeen) { reqExists = false; } request.RelatedNodeInList = NCQ.AddLast(request); return(request); }
public override void ProcessXEvent(XEvent e) { switch ((HostInterfaceEventType)e.Type) { case HostInterfaceEventType.GenerateNextIORequest: IORequest request = null; IORequestType reqType = IORequestType.Write; if (randomRequestTypeGenerator.Uniform(0, 1) < readRatio) { reqType = IORequestType.Read; ReceivedReadRequestCount++; } else { ReceivedWriteRequestCount++; } ulong lsn = 0; switch (addressDistributionType) { case InputStreamSynthetic.DistributionType.Uniform: lsn = randomAddressGenerator1.UniformULong(addressDistributionParam1, addressDistributionParam2); break; case InputStreamSynthetic.DistributionType.Normal: double templsn = randomAddressGenerator1.Normal(addressDistributionParam1, addressDistributionParam2); lsn = (uint)templsn; if (templsn < 0) { lsn = 0; } else if (templsn > this.FTL.AddressMapper.LargestLSN) { lsn = this.FTL.AddressMapper.LargestLSN; } break; case InputStreamSynthetic.DistributionType.Fixed: lsn = addressDistributionParam1; break; case InputStreamSynthetic.DistributionType.HotCold: if (randomHotColdRatioGenerator.Uniform(0, 1) < hotTrafficRate) { lsn = addressDistributionParam1 + randomHotAddressGenerator.UniformULong(0, hotAddressRange); } else { lsn = randomAddressGenerator1.UniformULong(0, this.FTL.AddressMapper.LargestLSN - hotAddressRange); if (lsn > addressDistributionParam1) { lsn += hotAddressRange; } } break; default: throw new Exception("Unknown distribution type for address."); } uint reqSize = 0; switch (requestSizeDistributionType) { case InputStreamSynthetic.DistributionType.Uniform: double tempReqSize = randomRequestSizeGenerator.Uniform(requestSizeDistributionParam1B, requestSizeDistributionParam2B); reqSize = (uint)(Math.Ceiling(tempReqSize / (double)FTL.SubPageCapacity)); if (reqSize == 0) { reqSize = 1; } break; case InputStreamSynthetic.DistributionType.Normal: tempReqSize = randomRequestSizeGenerator.Normal(requestSizeDistributionParam1B, requestSizeDistributionParam2B); reqSize = (uint)(Math.Ceiling(tempReqSize / (double)FTL.SubPageCapacity)); if (tempReqSize < 0) { reqSize = 1; } break; case InputStreamSynthetic.DistributionType.Fixed: reqSize = (uint)(Math.Ceiling(requestSizeDistributionParam1B / (double)FTL.SubPageCapacity)); break; default: throw new Exception("Uknown distribution type for requset size."); } request = new IORequest(XEngineFactory.XEngine.Time, lsn, reqSize, reqType); ReceivedRequestCount++; if (NCQ.Count < NCQSize) { request.RelatedNodeInList = NCQ.AddLast(request); SegmentIORequestNoCache_Sprinkler(request); FTL.IOScheduler.Schedule((uint)StreamPriorityClass.Urgent, AddressMappingModule.DefaultStreamID); //FTL.ServiceIORequest(); } else { HostQueue.AddLast(request); } if (ReceivedRequestCount < numberOfRequestsToBeSeen) { nextRequetArrivalTime = XEngineFactory.XEngine.Time + (ulong)(randomTimeIntervalGenerator.Exponential(averageRequestInterArrivalTime)); XEngineFactory.XEngine.EventList.InsertXEvent(new XEvent(nextRequetArrivalTime, this, null, 0)); } break; case HostInterfaceEventType.RequestCompletedByDRAM: IORequest targetRequest = e.Parameters as IORequest; SendEarlyResponseToHost(targetRequest); break; default: throw new Exception("Unhandled XEvent type"); } }
private void createFlashOperationRequest(ulong lpn, uint sizeInSubpages, uint state, IORequest currentIORequest) { if (currentIORequest.Type == IORequestType.Read) { InternalReadRequest subRequest = new InternalReadRequest(); myFTL.TotalPageReads++; myFTL.PageReadsForWorkload++; if (myFTL.AddressMapper.AddressMappingDomains[currentIORequest.StreamID].MappingTable.State[lpn] == 0) { for (var LPN = myFTL.currentActiveWriteLPNs[currentIORequest.StreamID].First; LPN != null; LPN = LPN.Next) { if (LPN.Value == lpn) { return; } } throw new Exception("Accessing an unwritten logical address for read!"); } myFTL.AddressMapper.ConvertPPNToPageAddress(myFTL.AddressMapper.AddressMappingDomains[currentIORequest.StreamID].MappingTable.PPN[lpn], subRequest.TargetPageAddress); subRequest.TargetFlashChip = myFTL.FlashChips[subRequest.TargetPageAddress.OverallFlashChipID]; subRequest.LPN = lpn; subRequest.PPN = myFTL.AddressMapper.AddressMappingDomains[currentIORequest.StreamID].MappingTable.PPN[lpn]; subRequest.SizeInSubpages = sizeInSubpages; subRequest.SizeInByte = sizeInSubpages * FTL.SubPageCapacity; subRequest.BodyTransferCycles = subRequest.SizeInByte / FTL.ChannelWidthInByte; subRequest.State = (myFTL.AddressMapper.AddressMappingDomains[currentIORequest.StreamID].MappingTable.State[lpn] & 0x7fffffff); subRequest.Type = InternalRequestType.Read; subRequest.RelatedIORequest = currentIORequest; //Arash: I have omitted a section of original code to ignore simultaneous read of same memory location currentIORequest.InternalRequestList.AddLast(subRequest); } else //currentRequest.Type == IORequestType.Write { InternalWriteRequest subRequest = new InternalWriteRequest(); myFTL.currentActiveWriteLPNs[currentIORequest.StreamID].AddLast(lpn); myFTL.TotalPageProgams++; myFTL.PageProgramsForWorkload++; subRequest.LPN = lpn; subRequest.PPN = 0; subRequest.SizeInSubpages = sizeInSubpages; subRequest.SizeInByte = sizeInSubpages * FTL.SubPageCapacity; subRequest.BodyTransferCycles = subRequest.SizeInByte / FTL.ChannelWidthInByte; subRequest.State = state; subRequest.Type = InternalRequestType.Write; subRequest.RelatedIORequest = currentIORequest; //The above line should be positioned before AllocateLocation. AllocatePlaneToWriteTransaction(subRequest); currentIORequest.InternalRequestList.AddLast(subRequest); } }
public void Segment(uint streamID) { if (Locked) { return; } Locked = true; while (myHandler.Flows[streamID].DeviceInternalQueue.Count > 0) { IORequest currentRequest = myHandler.Flows[streamID].DeviceInternalQueue.First.Value; myHandler.Flows[streamID].DeviceInternalQueue.RemoveFirst(); SegmentIORequestNoCache(currentRequest); IntegerPageAddress addr = null; foreach (InternalRequest ir in currentRequest.InternalRequestList) { addr = ir.TargetPageAddress; if (ir.Type == InternalRequestType.Read) { if (!myFTL.ResourceAccessTable.ChannelEntries[addr.ChannelID].WaitingReadRequests.ContainsKey(currentRequest)) { myFTL.ResourceAccessTable.ChannelEntries[addr.ChannelID].WaitingReadRequests.Add(currentRequest, 1); } else { myFTL.ResourceAccessTable.ChannelEntries[addr.ChannelID].WaitingReadRequests[currentRequest] = ((int)myFTL.ResourceAccessTable.ChannelEntries[addr.ChannelID].WaitingReadRequests[currentRequest]) + 1; } if (!myFTL.ResourceAccessTable.DieEntries[addr.ChannelID][addr.LocalFlashChipID][addr.DieID].WaitingReadRequests.ContainsKey(currentRequest)) { myFTL.ResourceAccessTable.DieEntries[addr.ChannelID][addr.LocalFlashChipID][addr.DieID].WaitingReadRequests.Add(currentRequest, 1); } else { myFTL.ResourceAccessTable.DieEntries[addr.ChannelID][addr.LocalFlashChipID][addr.DieID].WaitingReadRequests[currentRequest] = ((int)myFTL.ResourceAccessTable.DieEntries[addr.ChannelID][addr.LocalFlashChipID][addr.DieID].WaitingReadRequests[currentRequest]) + 1; } if (!myFTL.ResourceAccessTable.PlaneEntries[addr.ChannelID][addr.LocalFlashChipID][addr.DieID][addr.PlaneID].WaitingReadRequests.ContainsKey(currentRequest)) { myFTL.ResourceAccessTable.PlaneEntries[addr.ChannelID][addr.LocalFlashChipID][addr.DieID][addr.PlaneID].WaitingReadRequests.Add(currentRequest, 1); } else { myFTL.ResourceAccessTable.PlaneEntries[addr.ChannelID][addr.LocalFlashChipID][addr.DieID][addr.PlaneID].WaitingReadRequests[currentRequest] = ((int)myFTL.ResourceAccessTable.PlaneEntries[addr.ChannelID][addr.LocalFlashChipID][addr.DieID][addr.PlaneID].WaitingReadRequests[currentRequest]) + 1; } myHandler.Flows[streamID].ReadQueue.AddLast(ir as InternalReadRequest); myFTL.ResourceAccessTable.ChannelEntries[addr.ChannelID].WaitingReadCount++; myFTL.ResourceAccessTable.DieEntries[addr.ChannelID][addr.LocalFlashChipID][addr.DieID].WaitingReadCount++; myFTL.ResourceAccessTable.PlaneEntries[addr.ChannelID][addr.LocalFlashChipID][addr.DieID][addr.PlaneID].WaitingReadCount++; } else { if (!myFTL.ResourceAccessTable.ChannelEntries[addr.ChannelID].WaitingWriteRequests.ContainsKey(currentRequest)) { myFTL.ResourceAccessTable.ChannelEntries[addr.ChannelID].WaitingWriteRequests.Add(currentRequest, 1); } else { myFTL.ResourceAccessTable.ChannelEntries[addr.ChannelID].WaitingWriteRequests[currentRequest] = ((int)myFTL.ResourceAccessTable.ChannelEntries[addr.ChannelID].WaitingWriteRequests[currentRequest]) + 1; } if (!myFTL.ResourceAccessTable.DieEntries[addr.ChannelID][addr.LocalFlashChipID][addr.DieID].WaitingWriteRequests.ContainsKey(currentRequest)) { myFTL.ResourceAccessTable.DieEntries[addr.ChannelID][addr.LocalFlashChipID][addr.DieID].WaitingWriteRequests.Add(currentRequest, 1); } else { myFTL.ResourceAccessTable.DieEntries[addr.ChannelID][addr.LocalFlashChipID][addr.DieID].WaitingWriteRequests[currentRequest] = ((int)myFTL.ResourceAccessTable.DieEntries[addr.ChannelID][addr.LocalFlashChipID][addr.DieID].WaitingWriteRequests[currentRequest]) + 1; } if (!myFTL.ResourceAccessTable.PlaneEntries[addr.ChannelID][addr.LocalFlashChipID][addr.DieID][addr.PlaneID].WaitingWriteRequests.ContainsKey(currentRequest)) { myFTL.ResourceAccessTable.PlaneEntries[addr.ChannelID][addr.LocalFlashChipID][addr.DieID][addr.PlaneID].WaitingWriteRequests.Add(currentRequest, 1); } else { myFTL.ResourceAccessTable.PlaneEntries[addr.ChannelID][addr.LocalFlashChipID][addr.DieID][addr.PlaneID].WaitingWriteRequests[currentRequest] = ((int)myFTL.ResourceAccessTable.PlaneEntries[addr.ChannelID][addr.LocalFlashChipID][addr.DieID][addr.PlaneID].WaitingWriteRequests[currentRequest]) + 1; } myHandler.Flows[streamID].WriteQueue.AddLast(ir as InternalWriteRequest); myFTL.ResourceAccessTable.ChannelEntries[addr.ChannelID].WaitingWriteCount++; myFTL.ResourceAccessTable.DieEntries[addr.ChannelID][addr.LocalFlashChipID][addr.DieID].WaitingWriteCount++; myFTL.ResourceAccessTable.PlaneEntries[addr.ChannelID][addr.LocalFlashChipID][addr.DieID][addr.PlaneID].WaitingWriteCount++; if ((ir as InternalWriteRequest).UpdateRead != null) { addr = (ir as InternalWriteRequest).UpdateRead.TargetPageAddress; if (!myFTL.ResourceAccessTable.ChannelEntries[addr.ChannelID].WaitingReadRequests.ContainsKey(currentRequest)) { myFTL.ResourceAccessTable.ChannelEntries[addr.ChannelID].WaitingReadRequests.Add(currentRequest, 1); } else { myFTL.ResourceAccessTable.ChannelEntries[addr.ChannelID].WaitingReadRequests[currentRequest] = ((int)myFTL.ResourceAccessTable.ChannelEntries[addr.ChannelID].WaitingReadRequests[currentRequest]) + 1; } if (!myFTL.ResourceAccessTable.DieEntries[addr.ChannelID][addr.LocalFlashChipID][addr.DieID].WaitingReadRequests.ContainsKey(currentRequest)) { myFTL.ResourceAccessTable.DieEntries[addr.ChannelID][addr.LocalFlashChipID][addr.DieID].WaitingReadRequests.Add(currentRequest, 1); } else { myFTL.ResourceAccessTable.DieEntries[addr.ChannelID][addr.LocalFlashChipID][addr.DieID].WaitingReadRequests[currentRequest] = ((int)myFTL.ResourceAccessTable.DieEntries[addr.ChannelID][addr.LocalFlashChipID][addr.DieID].WaitingReadRequests[currentRequest]) + 1; } if (!myFTL.ResourceAccessTable.PlaneEntries[addr.ChannelID][addr.LocalFlashChipID][addr.DieID][addr.PlaneID].WaitingReadRequests.ContainsKey(currentRequest)) { myFTL.ResourceAccessTable.PlaneEntries[addr.ChannelID][addr.LocalFlashChipID][addr.DieID][addr.PlaneID].WaitingReadRequests.Add(currentRequest, 1); } else { myFTL.ResourceAccessTable.PlaneEntries[addr.ChannelID][addr.LocalFlashChipID][addr.DieID][addr.PlaneID].WaitingReadRequests[currentRequest] = ((int)myFTL.ResourceAccessTable.PlaneEntries[addr.ChannelID][addr.LocalFlashChipID][addr.DieID][addr.PlaneID].WaitingReadRequests[currentRequest]) + 1; } myHandler.Flows[streamID].ReadQueue.AddLast((ir as InternalWriteRequest).UpdateRead); myFTL.ResourceAccessTable.ChannelEntries[addr.ChannelID].WaitingReadCount++; myFTL.ResourceAccessTable.DieEntries[addr.ChannelID][addr.LocalFlashChipID][addr.DieID].WaitingReadCount++; myFTL.ResourceAccessTable.PlaneEntries[addr.ChannelID][addr.LocalFlashChipID][addr.DieID][addr.PlaneID].WaitingReadCount++; } } (myFTL.IOScheduler as IOSchedulerRPB).UpdateGCQueuePriority(ir.TargetPageAddress); } } Locked = false; myFTL.IOScheduler.Schedule((uint)myHandler.Flows[streamID].PriorityClass, streamID); }
protected override bool updateStatistics(IORequest targetIORequest) { thisRoundHandledRequestsCount++;//used in replay return(base.updateStatistics(targetIORequest)); }
public override IORequest GetNextIORequest(HostInterface hostInterface, bool foldAddress, bool ignoreUnallocatedReads) { IORequest request = null; if (NextInputLine != null) { #region GenerateRequest ulong lsn = AddressOffset + ulong.Parse(NextInputLine[HostInterface.ASCIITraceAddressColumn]); uint size = uint.Parse(NextInputLine[HostInterface.ASCIITraceSizeColumn]); if (hostInterface.FTL.AddressMapper.CheckRequestAddress(_id, lsn, size, foldAddress)) { if (foldAddress) { lsn = lsn % hostInterface.FTL.AddressMapper.AddressMappingDomains[_id].LargestLSN; } if (NextInputLine[HostInterface.ASCIITraceTypeColumn] == HostInterface.ASCIITraceWriteCode)//write request in ascii traces { request = new IORequest(_id, TimeOffset + ulong.Parse(NextInputLine[HostInterface.ASCIITraceTimeColumn]), lsn, size, IORequestType.Write); ReceivedWriteRequestCount++; ReceivedRequestCount++; request.RelatedNodeInList = SubmissionQueue.AddLast(request); if (HeadRequest == null) { HeadRequest = request.RelatedNodeInList; } } else//read request in ascii traces { bool goodRead = true; if (ignoreUnallocatedReads) { if (!hostInterface.FTL.AddressMapper.CheckReadRequest(_id, lsn, size)) { goodRead = false; IgnoredRequestsCount++; } } request = new IORequest(_id, TimeOffset + ulong.Parse(NextInputLine[HostInterface.ASCIITraceTimeColumn]), lsn, size, IORequestType.Read); ReceivedReadRequestCount++; ReceivedRequestCount++; if (goodRead) { request.RelatedNodeInList = SubmissionQueue.AddLast(request); if (HeadRequest == null) { HeadRequest = request.RelatedNodeInList; } } else { request.ToBeIgnored = true; } } } #endregion #region PrepareNextRequest if (_inputFile.Peek() >= 0) { if (ReceivedRequestCount < NumberOfRequestsToGenerate) { NextInputLine = _inputFile.ReadLine().Split(HostInterface.Separator); ulong eventTime = TimeOffset + ulong.Parse(NextInputLine[HostInterface.ASCIITraceTimeColumn]); XEngineFactory.XEngine.EventList.InsertXEvent(new XEvent(eventTime, hostInterface, _id, 0)); } } else { NextInputLine = null; if (XEngineFactory.XEngine.Time < SimulationStopTime) { _inputFile.Close(); _inputFile = new StreamReader(_traceFilePath); if (_inputFile.Peek() >= 0) { NextInputLine = _inputFile.ReadLine().Split(HostInterface.Separator); thisRoundHandledRequestsCount = 0; thisRoundSumResponseTime = 0; thisRoundHandledReadRequestsCount = 0; thisRoundSumResponseTimeR = 0; thisRoundHandledWriteRequestsCount = 0; thisRoundSumResponseTimeW = 0; } CurrentReplayRound++; TimeOffset = XEngineFactory.XEngine.Time; ulong eventTime = TimeOffset + ulong.Parse(NextInputLine[HostInterface.ASCIITraceTimeColumn]); XEngineFactory.XEngine.EventList.InsertXEvent(new XEvent(eventTime, hostInterface, _id, 0)); AddressOffset = ReplayAddressOffset[CurrentReplayRound - 1]; Console.WriteLine("\n\n******************************************"); Console.WriteLine("* Round {0} of {1} execution started *", CurrentReplayRound, FlowName); Console.WriteLine("******************************************\n"); } } #endregion } return(request); }
public override IORequest GetNextIORequest(HostInterface hostInterface, bool foldAddress, bool ignoreUnallocatedReads) { ReceivedRequestCount++; IORequestType reqType = IORequestType.Write; if (randomRequestTypeGenerator.Uniform(0, 1) < readRatio) { reqType = IORequestType.Read; ReceivedReadRequestCount++; } else { ReceivedWriteRequestCount++; } ulong lsn = 0; switch (addressDistributionType) { case DistributionType.Uniform: lsn = randomAddressGenerator1.UniformULong((ulong)(_addressDistributionParam1 * AddressMappingDomain.LargestLSN) , ((ulong)_addressDistributionParam2 * AddressMappingDomain.LargestLSN)); break; case DistributionType.Normal: double templsn = randomAddressGenerator1.Normal(_addressDistributionParam1, _addressDistributionParam2); lsn = (uint)templsn; if (templsn < 0) { lsn = 0; } else if (templsn > AddressMappingDomain.LargestLSN) { lsn = AddressMappingDomain.LargestLSN; } break; case DistributionType.HotCold: if (randomHotColdRatioGenerator.Uniform(0, 1) < hotTrafficRate) { lsn = _addressDistributionParam1 + randomHotAddressGenerator.UniformULong(0, hotAddressRange); } else { lsn = randomAddressGenerator1.UniformULong(0, AddressMappingDomain.LargestLSN - hotAddressRange); if (lsn > _addressDistributionParam1) { lsn += hotAddressRange; } } break; case DistributionType.Fixed: default: throw new Exception("Unknown distribution type for address."); } uint reqSize = 0; switch (requestSizeDistributionType) { case DistributionType.Uniform: double tempReqSize = randomRequestSizeGenerator.Uniform(_requestSizeDistributionParam1Sector, _requestSizeDistributionParam2Sector); reqSize = (uint)(Math.Ceiling(tempReqSize)); if (reqSize == 0) { reqSize = 1; } break; case DistributionType.Normal: tempReqSize = randomRequestSizeGenerator.Normal(_requestSizeDistributionParam1Sector, _requestSizeDistributionParam2Sector); reqSize = (uint)(Math.Ceiling(tempReqSize)); if (tempReqSize < 0) { reqSize = 1; } break; case DistributionType.Fixed: reqSize = _requestSizeDistributionParam1Sector; break; default: throw new Exception("Uknown distribution type for requset size."); } IORequest request = new IORequest(XEngineFactory.XEngine.Time, lsn, reqSize, reqType); request.RelatedNodeInList = SubmissionQueue.AddLast(request); if (HeadRequest == null) { HeadRequest = request.RelatedNodeInList; } if (ReceivedRequestCount < NumberOfRequestsToGenerate) { nextRequetArrivalTime = XEngineFactory.XEngine.Time + (ulong)(randomTimeIntervalGenerator.Exponential(averageRequestInterArrivalTime)); if (nextRequetArrivalTime <= SimulationStopTime) { XEngineFactory.XEngine.EventList.InsertXEvent(new XEvent(nextRequetArrivalTime, hostInterface, _id, 0)); } } return(request); }
public override void SendResponseToHost(InternalRequest internalReq) { sumOfInternalRequestLifeTime += (XEngineFactory.XEngine.Time - internalReq.IssueTime) / 1000; //Nanoseconds is converted to microseconds sumOfInternalRequestExecutionTime += internalReq.ExecutionTime / 1000; //Nanoseconds is converted to microseconds sumOfInternalRequestTransferTime += internalReq.TransferTime / 1000; //Nanoseconds is converted to microseconds sumOfInternalRequestWaitingTime += (XEngineFactory.XEngine.Time - (internalReq.IssueTime + internalReq.ExecutionTime + internalReq.TransferTime)) / 1000; //Nanoseconds is converted to microseconds totalFlashOperations++; if (gcStarted) { sumOfInternalRequestLifeTime_AGC += (XEngineFactory.XEngine.Time - internalReq.IssueTime) / 1000; sumOfInternalRequestExecutionTime_AGC += internalReq.ExecutionTime / 1000; sumOfInternalRequestTransferTime_AGC += internalReq.TransferTime / 1000; sumOfInternalRequestWaitingTime_AGC += (XEngineFactory.XEngine.Time - (internalReq.IssueTime + internalReq.ExecutionTime + internalReq.TransferTime)) / 1000; totalFlashOperations_AGC++; } if (internalReq.Type == InternalRequestType.Read) { sumOfReadRequestLifeTime += (XEngineFactory.XEngine.Time - internalReq.IssueTime) / 1000; sumOfReadRequestExecutionTime += internalReq.ExecutionTime / 1000; sumOfReadRequestTransferTime += internalReq.TransferTime / 1000; sumOfReadRequestWaitingTime += (XEngineFactory.XEngine.Time - (internalReq.IssueTime + internalReq.ExecutionTime + internalReq.TransferTime)) / 1000; totalReadOperations++; if (gcStarted) { sumOfReadRequestLifeTime_AGC += (XEngineFactory.XEngine.Time - internalReq.IssueTime) / 1000; sumOfReadRequestExecutionTime_AGC += internalReq.ExecutionTime / 1000; sumOfReadRequestTransferTime_AGC += internalReq.TransferTime / 1000; sumOfReadRequestWaitingTime_AGC += (XEngineFactory.XEngine.Time - (internalReq.IssueTime + internalReq.ExecutionTime + internalReq.TransferTime)) / 1000; totalReadOperations_AGC++; } } else { FTL.OnLPNServiced(internalReq.RelatedIORequest.StreamID, internalReq.LPN); sumOfProgramRequestLifeTime += (XEngineFactory.XEngine.Time - internalReq.IssueTime) / 1000; sumOfProgramRequestExecutionTime += internalReq.ExecutionTime / 1000; sumOfProgramRequestTransferTime += internalReq.TransferTime / 1000; sumOfProgramRequestWaitingTime += (XEngineFactory.XEngine.Time - (internalReq.IssueTime + internalReq.ExecutionTime + internalReq.TransferTime)) / 1000; totalProgramOperations++; if (gcStarted) { sumOfProgramRequestLifeTime_AGC += (XEngineFactory.XEngine.Time - internalReq.IssueTime) / 1000; sumOfProgramRequestExecutionTime_AGC += internalReq.ExecutionTime / 1000; sumOfProgramRequestTransferTime_AGC += internalReq.TransferTime / 1000; sumOfProgramRequestWaitingTime_AGC += (XEngineFactory.XEngine.Time - (internalReq.IssueTime + internalReq.ExecutionTime + internalReq.TransferTime)) / 1000; totalProgramOperations_AGC++; } } IORequest targetIORequest = internalReq.RelatedIORequest; if (_inputStreams[targetIORequest.StreamID].WriteToCompletionQueue(internalReq, requestProcessingTime)) { checked { try { sumResponseTime += (targetIORequest.ResponseTime / 1000); } catch (OverflowException ex) { Console.WriteLine("Overflow exception occured while calculating statistics in HostInterface."); if (overflowOccured) { throw new Exception("I can just handle one overflow event, but I received the second one!"); } overflowOccured = true; XEngineFactory.XEngine.StopSimulation(); return; } } thisRoundSumResponseTime += targetIORequest.ResponseTime / 1000; if (minResponseTime > targetIORequest.ResponseTime) { minResponseTime = targetIORequest.ResponseTime; } else if (maxResponseTime < targetIORequest.ResponseTime) { maxResponseTime = targetIORequest.ResponseTime; } transferredBytesCount += targetIORequest.SizeInByte; handledRequestsCount++; //used for general statistics thisRoundHandledRequestsCount++; //used in replay if (gcStarted) { sumResponseTime_AGC += (targetIORequest.ResponseTime / 1000); if (minResponseTime_AGC > targetIORequest.ResponseTime) { minResponseTime_AGC = targetIORequest.ResponseTime; } else if (maxResponseTime_AGC < targetIORequest.ResponseTime) { maxResponseTime_AGC = targetIORequest.ResponseTime; } transferredBytesCount_AGC += targetIORequest.SizeInByte; handledRequestsCount_AGC++;//used for general statistics } if (targetIORequest.Type == IORequestType.Write) { sumResponseTimeW += (targetIORequest.ResponseTime / 1000); thisRoundSumResponseTimeW += (targetIORequest.ResponseTime / 1000); transferredBytesCountW += targetIORequest.SizeInByte; handledWriteRequestsCount++; thisRoundHandledWriteRequestsCount++; if (minResponseTimeW > targetIORequest.ResponseTime) { minResponseTimeW = targetIORequest.ResponseTime; } else if (maxResponseTimeW < targetIORequest.ResponseTime) { maxResponseTimeW = targetIORequest.ResponseTime; } if (gcStarted) { sumResponseTimeW_AGC += (targetIORequest.ResponseTime / 1000); transferredBytesCountW_AGC += targetIORequest.SizeInByte; handledWriteRequestsCount_AGC++; if (minResponseTimeW_AGC > targetIORequest.ResponseTime) { minResponseTimeW_AGC = targetIORequest.ResponseTime; } else if (maxResponseTimeW_AGC < targetIORequest.ResponseTime) { maxResponseTimeW_AGC = targetIORequest.ResponseTime; } } } else { sumResponseTimeR += (targetIORequest.ResponseTime / 1000); thisRoundSumResponseTimeR += (targetIORequest.ResponseTime / 1000); transferredBytesCountR += targetIORequest.SizeInByte; handledReadRequestsCount++; thisRoundHandledReadRequestsCount++; if (minResponseTimeR > targetIORequest.ResponseTime) { minResponseTimeR = targetIORequest.ResponseTime; } else if (maxResponseTimeR < targetIORequest.ResponseTime) { maxResponseTimeR = targetIORequest.ResponseTime; } if (gcStarted) { sumResponseTimeR_AGC += (targetIORequest.ResponseTime / 1000); transferredBytesCountR_AGC += targetIORequest.SizeInByte; handledReadRequestsCount_AGC++; if (minResponseTimeR_AGC > targetIORequest.ResponseTime) { minResponseTimeR_AGC = targetIORequest.ResponseTime; } else if (maxResponseTimeR_AGC < targetIORequest.ResponseTime) { maxResponseTimeR_AGC = targetIORequest.ResponseTime; } } } if ((handledRequestsCount / (double)totalRequestsToGenerate) > nextAnnouncementMilestone) { nextAnnouncementMilestone += announcementStep; OnStatReady(); } OnIORequestCompleted(targetIORequest.StreamID); }//_inputStreams[targetIORequest.StreamID].WriteToCompletionQueue... }
/* When an IO request is handled without creating any InternalRequest * this function is invoked (i.e., IO request is handled by cache or by requests currently being serviced. * For example if we have a read request for an lpn which is simultaneously being written with another * request, therefore we can simply return the value of write without performing any flash read operation.)*/ public override void SendEarlyResponseToHost(IORequest targetIORequest) { _inputStreams[targetIORequest.StreamID].WriteToCompletionQueue(targetIORequest, requestProcessingTime); checked { try { sumResponseTime += (targetIORequest.ResponseTime / 1000); } catch (OverflowException) { Console.WriteLine("Overflow exception occured while calculating statistics in HostInterface."); if (overflowOccured) { throw new Exception("I can just handle one overflow event, but I received the second one!"); } overflowOccured = true; XEngineFactory.XEngine.StopSimulation(); return; } } thisRoundSumResponseTime += targetIORequest.ResponseTime / 1000; transferredBytesCount += targetIORequest.SizeInByte; handledRequestsCount++; //used for general statistics thisRoundHandledRequestsCount++; //used in replay if (gcStarted) { sumResponseTime_AGC += (targetIORequest.ResponseTime / 1000); transferredBytesCount_AGC += targetIORequest.SizeInByte; handledRequestsCount_AGC++;//used for general statistics } if (targetIORequest.Type == IORequestType.Write) { sumResponseTimeW += (targetIORequest.ResponseTime / 1000); thisRoundSumResponseTimeW += (targetIORequest.ResponseTime / 1000); transferredBytesCountW += targetIORequest.SizeInByte; handledWriteRequestsCount++; thisRoundHandledWriteRequestsCount++; if (gcStarted) { sumResponseTimeW_AGC += (targetIORequest.ResponseTime / 1000); transferredBytesCountW_AGC += targetIORequest.SizeInByte; handledWriteRequestsCount_AGC++; } } else { sumResponseTimeR += (targetIORequest.ResponseTime / 1000); thisRoundSumResponseTimeR += (targetIORequest.ResponseTime / 1000); transferredBytesCountR += targetIORequest.SizeInByte; handledReadRequestsCount++; thisRoundHandledReadRequestsCount++; if (gcStarted) { sumResponseTimeR_AGC += (targetIORequest.ResponseTime / 1000); transferredBytesCountR_AGC += targetIORequest.SizeInByte; handledReadRequestsCount_AGC++; } } if ((handledRequestsCount / (double)totalRequestsToGenerate) > nextAnnouncementMilestone) { nextAnnouncementMilestone += announcementStep; OnStatReady(); } OnIORequestCompleted(targetIORequest.StreamID); }
public void CheckCache(IORequest currentRequest) { /* uint index, state; * uint flag = 0, need_distb_flag, lsn_flag; * CacheUnit buffer_node; * CacheUnit key = new CacheUnit(); * uint mask = 0; * uint offset1 = 0, offset2 = 0; * * bool requestedCompletedInDRAM = true; * uint full_page = ~(0xffffffff << (int)_FTL.SubpageNoPerPage); * ulong lsn = currentRequest.LSN; * ulong lpn = lsn / _FTL.SubpageNoPerPage; * ulong lastLpn = (lsn + currentRequest.SizeInSubpages - 1) / _FTL.SubpageNoPerPage; * ulong firstLpn = lpn; * * currentRequest.NeedDistrFlag = new uint[(lastLpn - firstLpn + 1) * _FTL.SubpageNoPerPage / 32 + 1]; * * if (currentRequest.Type == IORequestType.Read) * { * while (lpn <= lastLpn) * { * need_distb_flag = full_page; * key.LPN = lpn; * buffer_node = Buffer.Find(key); * while ((buffer_node != null) && (lsn < (lpn + 1) * _FTL.SubpageNoPerPage) && (lsn <= (currentRequest.LSN + currentRequest.SizeInSubpages - 1))) * { * lsn_flag = full_page; * mask = (uint)(1 << (int)(lsn % _FTL.SubpageNoPerPage)); * if (mask > 31) * { * Console.WriteLine("the subpage number is larger than 32!add some cases"); * Console.Read(); * } * else if ((buffer_node.ValidSectors & mask) == mask) * { * flag = 1; * lsn_flag = (uint)lsn & (~mask); * throw new Exception("ulong casted to uint. Needs considration"); * } * * if (flag == 1) * { * if (Buffer.buffer_head != buffer_node) * { * if (Buffer.buffer_tail == buffer_node) * { * buffer_node.LRU_link_pre.LRU_link_next = null; * Buffer.buffer_tail = buffer_node.LRU_link_pre; * } * else * { * buffer_node.LRU_link_pre.LRU_link_next = buffer_node.LRU_link_next; * buffer_node.LRU_link_next.LRU_link_pre = buffer_node.LRU_link_pre; * } * buffer_node.LRU_link_next = Buffer.buffer_head; * Buffer.buffer_head.LRU_link_pre = buffer_node; * buffer_node.LRU_link_pre = null; * Buffer.buffer_head = buffer_node; * } * Buffer.read_hit++; * currentRequest.CompleteLSNCount++; * } * else if (flag == 0) * { * Buffer.read_miss_hit++; * } * need_distb_flag = need_distb_flag & lsn_flag; * * flag = 0; * lsn++; * } * * index = (uint)((lpn - firstLpn) / (32 / _FTL.SubpageNoPerPage)); * currentRequest.NeedDistrFlag[index] = currentRequest.NeedDistrFlag[index] | (need_distb_flag << (int)(((lpn - firstLpn) % (32 / _FTL.SubpageNoPerPage)) * _FTL.SubpageNoPerPage)); * lpn++; * } * * for (int j = 0; j <= (int)((lastLpn - firstLpn + 1) * (_FTL.SubpageNoPerPage) / 32); j++)//? maybe: checks that the operation done completely and nothig remain. * if (currentRequest.NeedDistrFlag[j] != 0) * requestedCompletedInDRAM = false; * } * else// if (currentRequest.Type == IORequestType.Write) * { * while (lpn <= lastLpn) * { * mask = ~(0xffffffff << (int)(_FTL.SubpageNoPerPage)); * state = mask; * if (lpn == firstLpn) * { * offset1 = (uint)((_FTL.SubpageNoPerPage) - ((lpn + 1) * _FTL.SubpageNoPerPage - currentRequest.LSN)); * state = state & (0xffffffff << (int)offset1); * } * if (lpn == lastLpn) * { * offset2 = (uint)(_FTL.SubpageNoPerPage - ((lpn + 1) * _FTL.SubpageNoPerPage - (currentRequest.LSN + currentRequest.SizeInSubpages))); * state = state & (~(0xffffffff << (int)offset2)); * } * CacheUpdate(lpn, state, currentRequest); * lpn++; * } * } * * if (requestedCompletedInDRAM && (currentRequest.InternalRequestList.Count == 0)) * XEngineFactory.XEngine.EventList.InsertXEvent(new XEvent(XEngineFactory.XEngine.Time + this.DRAMServiceTime, _FTL.HostInterface, currentRequest, (int)HostInterface.HostInterfaceEventType.RequestCompletedByDRAM)); */ }
private void CacheUpdate(ulong lpn, uint state, IORequest currentRequest) { /*ulong write_back_count; * uint i, hit_flag, add_flag; * ulong lsn; * CacheUnit buffer_node = null; * CacheUnit pt; * CacheUnit new_node = null; * CacheUnit key = new CacheUnit(); * * uint sub_req_state = 0, sub_req_size = 0; * ulong sub_req_lpn = 0; * * uint sectorCount = FTL.SizeInSubpages(state); * key.LPN = lpn; * buffer_node = Buffer.Find(key); * * if (buffer_node == null) * { * if (Buffer.MaxBufferSector - Buffer.OccupiedSectorCount < sectorCount) * { * write_back_count = sectorCount - (Buffer.MaxBufferSector - Buffer.OccupiedSectorCount); * Buffer.write_miss_hit += write_back_count; * while (write_back_count > 0) * { * sub_req_state = Buffer.buffer_tail.ValidSectors; * sub_req_size = _FTL.SizeInSubpages(Buffer.buffer_tail.ValidSectors); * sub_req_lpn = Buffer.buffer_tail.LPN; * FTL.CreatFlashTransaction(sub_req_lpn, sub_req_size, sub_req_state, currentRequest);//?create_sub_request done'nt exist. * * Buffer.OccupiedSectorCount = Buffer.OccupiedSectorCount - sub_req_size; * pt = Buffer.buffer_tail; * Buffer.Del(pt); * if (Buffer.buffer_head.LRU_link_next == null) * { * Buffer.buffer_head = null; * Buffer.buffer_tail = null; * } * else * { * Buffer.buffer_tail = Buffer.buffer_tail.LRU_link_pre; * Buffer.buffer_tail.LRU_link_next = null; * } * write_back_count -= sub_req_size; * } * } * new_node = new CacheUnit(); * new_node.LPN = lpn; * new_node.ValidSectors = state; * new_node.DirtyClean = state; * new_node.LRU_link_pre = null; * new_node.LRU_link_next = Buffer.buffer_head; * if (Buffer.buffer_head != null) * { * Buffer.buffer_head.LRU_link_pre = new_node; * } * else * { * Buffer.buffer_tail = new_node; * } * Buffer.buffer_head = new_node; * new_node.LRU_link_pre = null; * Buffer.Add(new_node); * Buffer.OccupiedSectorCount += sectorCount; * } * * else * { * for (i = 0; i < _FTL.SubpageNoPerPage; i++) * { * if ((state >> (int)i) % 2 != 0) * { * lsn = lpn * _FTL.SubpageNoPerPage + i; * hit_flag = 0; * hit_flag = (uint)((buffer_node.ValidSectors) & (0x00000001 << (int)i)); * * if (hit_flag != 0) * { * if (currentRequest != null) * { * if (Buffer.buffer_head != buffer_node) * { * if (Buffer.buffer_tail == buffer_node) * { * Buffer.buffer_tail = buffer_node.LRU_link_pre; * buffer_node.LRU_link_pre.LRU_link_next = null; * } * else if (buffer_node != Buffer.buffer_head) * { * buffer_node.LRU_link_pre.LRU_link_next = buffer_node.LRU_link_next; * buffer_node.LRU_link_next.LRU_link_pre = buffer_node.LRU_link_pre; * } * buffer_node.LRU_link_next = Buffer.buffer_head; * Buffer.buffer_head.LRU_link_pre = buffer_node; * buffer_node.LRU_link_pre = null; * Buffer.buffer_head = buffer_node; * } * Buffer.write_hit++; * currentRequest.CompleteLSNCount++;//in moteghaiier vojood nadare. * } * } * else * { * Buffer.write_miss_hit++; * if (Buffer.OccupiedSectorCount >= Buffer.MaxBufferSector) * { * if (buffer_node == Buffer.buffer_tail) * { * pt = Buffer.buffer_tail.LRU_link_pre; * Buffer.buffer_tail.LRU_link_pre = pt.LRU_link_pre; * Buffer.buffer_tail.LRU_link_pre.LRU_link_next = Buffer.buffer_tail; * Buffer.buffer_tail.LRU_link_next = pt; * pt.LRU_link_next = null; * pt.LRU_link_pre = Buffer.buffer_tail; * Buffer.buffer_tail = pt; * } * sub_req_state = Buffer.buffer_tail.ValidSectors; * sub_req_size = _FTL.SizeInSubpages(Buffer.buffer_tail.ValidSectors); * sub_req_lpn = Buffer.buffer_tail.LPN; * FTL.CreatFlashTransaction(sub_req_lpn, sub_req_size, sub_req_state, currentRequest);//create sub request deosn'g exsist * * Buffer.OccupiedSectorCount = Buffer.OccupiedSectorCount - sub_req_size; * pt = Buffer.buffer_tail; * Buffer.Del(pt); * * if (Buffer.buffer_head.LRU_link_next == null) * { * Buffer.buffer_head = null; * Buffer.buffer_tail = null; * } * else * { * Buffer.buffer_tail = Buffer.buffer_tail.LRU_link_pre; * Buffer.buffer_tail.LRU_link_next = null; * } * pt.LRU_link_next = null; * pt.LRU_link_pre = null; * //AVL_TREENODE_FREE(ssd->dram->buffer, (TREE_NODE*)pt); * pt = null; * } * * add_flag = (uint)(0x00000001 << (int)(lsn % _FTL.SubpageNoPerPage)); * if (Buffer.buffer_head != buffer_node) * { * if (Buffer.buffer_tail == buffer_node) * { * buffer_node.LRU_link_pre.LRU_link_next = null; * Buffer.buffer_tail = buffer_node.LRU_link_pre; * } * else * { * buffer_node.LRU_link_pre.LRU_link_next = buffer_node.LRU_link_next; * buffer_node.LRU_link_next.LRU_link_pre = buffer_node.LRU_link_pre; * } * buffer_node.LRU_link_next = Buffer.buffer_head; * Buffer.buffer_head.LRU_link_pre = buffer_node; * buffer_node.LRU_link_pre = null; * Buffer.buffer_head = buffer_node; * } * buffer_node.ValidSectors = buffer_node.ValidSectors | add_flag; * buffer_node.DirtyClean = buffer_node.DirtyClean | add_flag;//no dirty clean flag * Buffer.OccupiedSectorCount++; * } * } * } * }*/ }